src/enc/picture_csp.c
int WebPPictureYUVAToARGB(WebPPicture* picture) {
  if (picture == NULL) return 0;
  if (picture->y == NULL || picture->u == NULL || picture->v == NULL) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
  }
  if ((picture->colorspace & WEBP_CSP_ALPHA_BIT) && picture->a == NULL) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
  }
  if ((picture->colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
  }
  // Allocate a new argb buffer (discarding the previous one).
  if (!WebPPictureAllocARGB(picture, picture->width, picture->height)) return 0;
  picture->use_argb = 1;

  // Convert
  {
    int y;
    const int width = picture->width;
    const int height = picture->height;
    const int argb_stride = 4 * picture->argb_stride;
    uint8_t* dst = (uint8_t*)picture->argb;
    const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
    WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST);

    // First row, with replicated top samples.
    upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
    cur_y += picture->y_stride;
    dst += argb_stride;
    // Center rows.
    for (y = 1; y + 1 < height; y += 2) {
      const uint8_t* const top_u = cur_u;
      const uint8_t* const top_v = cur_v;
      cur_u += picture->uv_stride;
      cur_v += picture->uv_stride;
      upsample(cur_y, cur_y + picture->y_stride, top_u, top_v, cur_u, cur_v,
               dst, dst + argb_stride, width);
      cur_y += 2 * picture->y_stride;
      dst += 2 * argb_stride;
    }
    // Last row (if needed), with replicated bottom samples.
    if (height > 1 && !(height & 1)) {
      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
    }
    // Insert alpha values if needed, in replacement for the default 0xff ones.
    if (picture->colorspace & WEBP_CSP_ALPHA_BIT) {
      for (y = 0; y < height; ++y) {
        uint32_t* const argb_dst = picture->argb + y * picture->argb_stride;
        const uint8_t* const src = picture->a + y * picture->a_stride;
        int x;
        for (x = 0; x < width; ++x) {
          argb_dst[x] = (argb_dst[x] & 0x00ffffffu) | ((uint32_t)src[x] << 24);
        }
      }
    }
  }
  return 1;
}
//------------------------------------------------------------------------------
// call for YUVA -> ARGB conversion
call for YUVA -> ARGB conversion
call for YUVA - > ARGB conversion
int WebPPictureYUVAToARGB(WebPPicture* picture) {
  if (picture == NULL) return 0;
  if (picture->y == NULL || picture->u == NULL || picture->v == NULL) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
  }
  if ((picture->colorspace & WEBP_CSP_ALPHA_BIT) && picture->a == NULL) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_NULL_PARAMETER);
  }
  if ((picture->colorspace & WEBP_CSP_UV_MASK) != WEBP_YUV420) {
    return WebPEncodingSetError(picture, VP8_ENC_ERROR_INVALID_CONFIGURATION);
  }
  if (!WebPPictureAllocARGB(picture, picture->width, picture->height)) return 0;
  picture->use_argb = 1;
  {
    int y;
    const int width = picture->width;
    const int height = picture->height;
    const int argb_stride = 4 * picture->argb_stride;
    uint8_t* dst = (uint8_t*)picture->argb;
    const uint8_t *cur_u = picture->u, *cur_v = picture->v, *cur_y = picture->y;
    WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST);
    upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
    cur_y += picture->y_stride;
    dst += argb_stride;
    for (y = 1; y + 1 < height; y += 2) {
      const uint8_t* const top_u = cur_u;
      const uint8_t* const top_v = cur_v;
      cur_u += picture->uv_stride;
      cur_v += picture->uv_stride;
      upsample(cur_y, cur_y + picture->y_stride, top_u, top_v, cur_u, cur_v,
               dst, dst + argb_stride, width);
      cur_y += 2 * picture->y_stride;
      dst += 2 * argb_stride;
    }
    if (height > 1 && !(height & 1)) {
      upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width);
    }
    if (picture->colorspace & WEBP_CSP_ALPHA_BIT) {
      for (y = 0; y < height; ++y) {
        uint32_t* const argb_dst = picture->argb + y * picture->argb_stride;
        const uint8_t* const src = picture->a + y * picture->a_stride;
        int x;
        for (x = 0; x < width; ++x) {
          argb_dst[x] = (argb_dst[x] & 0x00ffffffu) | ((uint32_t)src[x] << 24);
        }
      }
    }
  }
  return 1;
}
int WebPPictureYUVAToARGB ( WebPPicture * picture ) { if ( picture == NULL ) return 0 ; if ( picture -> y == NULL || picture -> u == NULL || picture -> v == NULL ) { return WebPEncodingSetError ( picture , VP8_ENC_ERROR_NULL_PARAMETER ) ; } if ( ( picture -> colorspace & WEBP_CSP_ALPHA_BIT ) && picture -> a == NULL ) { return WebPEncodingSetError ( picture , VP8_ENC_ERROR_NULL_PARAMETER ) ; } if ( ( picture -> colorspace & WEBP_CSP_UV_MASK ) != WEBP_YUV420 ) { return WebPEncodingSetError ( picture , VP8_ENC_ERROR_INVALID_CONFIGURATION ) ; } if ( ! WebPPictureAllocARGB ( picture , picture -> width , picture -> height ) ) return 0 ; picture -> use_argb = 1 ; { int y ; const int width = picture -> width ; const int height = picture -> height ; const int argb_stride = 4 * picture -> argb_stride ; uint8_t * dst = ( uint8_t * ) picture -> argb ; const uint8_t * cur_u = picture -> u , * cur_v = picture -> v , * cur_y = picture -> y ; WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter ( ALPHA_IS_LAST ) ; upsample ( cur_y , NULL , cur_u , cur_v , cur_u , cur_v , dst , NULL , width ) ; cur_y += picture -> y_stride ; dst += argb_stride ; for ( y = 1 ; y + 1 < height ; y += 2 ) { const uint8_t * const top_u = cur_u ; const uint8_t * const top_v = cur_v ; cur_u += picture -> uv_stride ; cur_v += picture -> uv_stride ; upsample ( cur_y , cur_y + picture -> y_stride , top_u , top_v , cur_u , cur_v , dst , dst + argb_stride , width ) ; cur_y += 2 * picture -> y_stride ; dst += 2 * argb_stride ; } if ( height > 1 && ! ( height & 1 ) ) { upsample ( cur_y , NULL , cur_u , cur_v , cur_u , cur_v , dst , NULL , width ) ; } if ( picture -> colorspace & WEBP_CSP_ALPHA_BIT ) { for ( y = 0 ; y < height ; ++ y ) { uint32_t * const argb_dst = picture -> argb + y * picture -> argb_stride ; const uint8_t * const src = picture -> a + y * picture -> a_stride ; int x ; for ( x = 0 ; x < width ; ++ x ) { argb_dst [ x ] = ( argb_dst [ x ] & 0x00ffffffu ) | ( ( uint32_t ) src [ x ] << 24 ) ; } } } } return 1 ; }
call for YUVA -> ARGB conversion
call for YUVA - > ARGB conversion
// Allocate a new argb buffer (discarding the previous one). // Convert // First row, with replicated top samples. // Center rows. // Last row (if needed), with replicated bottom samples. // Insert alpha values if needed, in replacement for the default 0xff ones.