コード例 #1
0
ファイル: buffer.c プロジェクト: Vanson/libwebp
VP8StatusCode WebPAllocateDecBuffer(int w, int h,
                                    const WebPDecoderOptions* const options,
                                    WebPDecBuffer* const out) {
    VP8StatusCode status;
    if (out == NULL || w <= 0 || h <= 0) {
        return VP8_STATUS_INVALID_PARAM;
    }
    if (options != NULL) {    // First, apply options if there is any.
        if (options->use_cropping) {
            const int cw = options->crop_width;
            const int ch = options->crop_height;
            const int x = options->crop_left & ~1;
            const int y = options->crop_top & ~1;
            if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) {
                return VP8_STATUS_INVALID_PARAM;   // out of frame boundary.
            }
            w = cw;
            h = ch;
        }
        if (options->use_scaling) {
            int scaled_width = options->scaled_width;
            int scaled_height = options->scaled_height;
            if (!WebPRescalerGetScaledDimensions(
                        w, h, &scaled_width, &scaled_height)) {
                return VP8_STATUS_INVALID_PARAM;
            }
            w = scaled_width;
            h = scaled_height;
        }
    }
    out->width = w;
    out->height = h;

    // Then, allocate buffer for real.
    status = AllocateBuffer(out);
    if (status != VP8_STATUS_OK) return status;

    // Use the stride trick if vertical flip is needed.
    if (options != NULL && options->flip) {
        status = WebPFlipBuffer(out);
    }
    return status;
}
コード例 #2
0
ファイル: webp.c プロジェクト: ZW19911104/libwebp
// Main flow
static VP8StatusCode DecodeInto(const uint8_t* const data, size_t data_size,
                                WebPDecParams* const params) {
  VP8StatusCode status;
  VP8Io io;
  WebPHeaderStructure headers;

  headers.data = data;
  headers.data_size = data_size;
  headers.have_all_data = 1;
  status = WebPParseHeaders(&headers);   // Process Pre-VP8 chunks.
  if (status != VP8_STATUS_OK) {
    return status;
  }

  assert(params != NULL);
  VP8InitIo(&io);
  io.data = headers.data + headers.offset;
  io.data_size = headers.data_size - headers.offset;
  WebPInitCustomIo(params, &io);  // Plug the I/O functions.

  if (!headers.is_lossless) {
    VP8Decoder* const dec = VP8New();
    if (dec == NULL) {
      return VP8_STATUS_OUT_OF_MEMORY;
    }
    dec->alpha_data_ = headers.alpha_data;
    dec->alpha_data_size_ = headers.alpha_data_size;

    // Decode bitstream header, update io->width/io->height.
    if (!VP8GetHeaders(dec, &io)) {
      status = dec->status_;   // An error occurred. Grab error status.
    } else {
      // Allocate/check output buffers.
      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
                                     params->output);
      if (status == VP8_STATUS_OK) {  // Decode
        // This change must be done before calling VP8Decode()
        dec->mt_method_ = VP8GetThreadMethod(params->options, &headers,
                                             io.width, io.height);
        VP8InitDithering(params->options, dec);
        if (!VP8Decode(dec, &io)) {
          status = dec->status_;
        }
      }
    }
    VP8Delete(dec);
  } else {
    VP8LDecoder* const dec = VP8LNew();
    if (dec == NULL) {
      return VP8_STATUS_OUT_OF_MEMORY;
    }
    if (!VP8LDecodeHeader(dec, &io)) {
      status = dec->status_;   // An error occurred. Grab error status.
    } else {
      // Allocate/check output buffers.
      status = WebPAllocateDecBuffer(io.width, io.height, params->options,
                                     params->output);
      if (status == VP8_STATUS_OK) {  // Decode
        if (!VP8LDecodeImage(dec)) {
          status = dec->status_;
        }
      }
    }
    VP8LDelete(dec);
  }

  if (status != VP8_STATUS_OK) {
    WebPFreeDecBuffer(params->output);
  } else {
    if (params->options != NULL && params->options->flip) {
      // This restores the original stride values if options->flip was used
      // during the call to WebPAllocateDecBuffer above.
      status = WebPFlipBuffer(params->output);
    }
  }
  return status;
}