bool WebpInput::open (const std::string &name, ImageSpec &spec) { m_filename = name; m_file = Filesystem::fopen(m_filename, "rb"); if (!m_file) { error ("Could not open file \"%s\"", m_filename.c_str()); return false; } fseek (m_file, 0, SEEK_END); m_image_size = ftell(m_file); fseek (m_file, 0, SEEK_SET); std::vector<uint8_t> encoded_image; encoded_image.resize(m_image_size, 0); size_t numRead = fread(&encoded_image[0], sizeof(uint8_t), encoded_image.size(), m_file); if (numRead != encoded_image.size()) { error ("Read failure for \"%s\" (expected %d bytes, read %d)", m_filename, encoded_image.size(), numRead); close (); return false; } int width = 0, height = 0; if(!WebPGetInfo(&encoded_image[0], encoded_image.size(), &width, &height)) { error ("%s is not a WebP image file", m_filename.c_str()); close(); return false; } const int CHANNEL_NUM = 4; m_scanline_size = width * CHANNEL_NUM; m_spec = ImageSpec(width, height, CHANNEL_NUM, TypeDesc::UINT8); spec = m_spec; if (!(m_decoded_image = WebPDecodeRGBA(&encoded_image[0], encoded_image.size(), &m_spec.width, &m_spec.height))) { error ("Couldn't decode %s", m_filename.c_str()); close(); return false; } return true; }
std::unique_ptr<DecodedImage> decodeWebpFromInputStream( JNIEnv* env, jobject is, PixelFormat pixel_format) { // get image into decoded heap auto encoded_image = readStreamFully(env, is); RETURNVAL_IF_EXCEPTION_PENDING({}); // extract metadata auto metadata = extractMetadata(env, encoded_image); RETURNVAL_IF_EXCEPTION_PENDING({}); // get pixels int image_width = 0; int image_height = 0; uint8_t* raw_pixels = nullptr; switch (pixel_format) { case PixelFormat::RGB: raw_pixels = WebPDecodeRGB( encoded_image.data(), encoded_image.size(), &image_width, &image_height); break; case PixelFormat::RGBA: raw_pixels = WebPDecodeRGBA( encoded_image.data(), encoded_image.size(), &image_width, &image_height); break; default: THROW_AND_RETURNVAL_IF(true, "unrecognized pixel format", {}); } auto pixels = pixels_t{raw_pixels, (void(*)(uint8_t*)) &free}; return std::unique_ptr<DecodedImage>{ new DecodedImage{ std::move(pixels), pixel_format, (unsigned int) image_width, (unsigned int) image_height, std::move(metadata)}}; }
PyObject* WebPDecodeRGBA_wrapper(PyObject* self, PyObject* args) { PyBytesObject *webp_string; int width; int height; uint8_t *webp; uint8_t *output; Py_ssize_t size; PyObject *ret; if (!PyArg_ParseTuple(args, "S", &webp_string)) { Py_INCREF(Py_None); return Py_None; } PyBytes_AsStringAndSize((PyObject *) webp_string, (char**)&webp, &size); output = WebPDecodeRGBA(webp, size, &width, &height); ret = PyBytes_FromStringAndSize((char*)output, width * height * 4); free(output); return Py_BuildValue("Sii", ret, width, height); }
uint8_t* webpDecodeRGBA( const uint8_t* data, size_t data_size, int* width, int* height ) { return WebPDecodeRGBA(data, data_size, width, height); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d W E B P I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadWEBPImage() reads an image in the WebP image format. % % The format of the ReadWEBPImage method is: % % Image *ReadWEBPImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadWEBPImage(const ImageInfo *image_info, ExceptionInfo *exception) { int height, width; Image *image; MagickBooleanType status; register PixelPacket *q; register ssize_t x; register unsigned char *p; size_t length; ssize_t count, y; unsigned char *stream, *pixels; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } length=(size_t) GetBlobSize(image); stream=(unsigned char *) AcquireQuantumMemory(length,sizeof(*stream)); if (stream == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,length,stream); if (count != (ssize_t) length) ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile"); pixels=(unsigned char *) WebPDecodeRGBA(stream,length,&width,&height); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); image->columns=(size_t) width; image->rows=(size_t) height; p=pixels; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetRedPixelComponent(q,ScaleCharToQuantum(*p++)); SetGreenPixelComponent(q,ScaleCharToQuantum(*p++)); SetBluePixelComponent(q,ScaleCharToQuantum(*p++)); SetOpacityPixelComponent(q,(QuantumRange-ScaleCharToQuantum(*p++))); if (q->opacity != OpaqueOpacity) image->matte=MagickTrue; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } free(pixels); pixels=(unsigned char *) NULL; return(image); }
bool WebPImageReader::decode() { surface = (unsigned int *)WebPDecodeRGBA(source, length, NULL, NULL); return surface != NULL; }
SWIGEXPORT jbyteArray JNICALL Java_com_google_webp_libwebpJNI_WebPDecodeRGBA(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jint jarg2, jintArray jarg3, jintArray jarg4) { jbyteArray jresult = 0 ; uint8_t *arg1 = (uint8_t *) 0 ; uint32_t arg2 ; int *arg3 = (int *) 0 ; int *arg4 = (int *) 0 ; jbyte *jarr1 ; int temp3 ; int temp4 ; uint8_t *result = 0 ; (void)jenv; (void)jcls; if (!SWIG_JavaArrayInSchar(jenv, &jarr1, &arg1, jarg1)) return 0; arg2 = (uint32_t)jarg2; { if (!jarg3) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg3) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg3 = &temp3; } { if (!jarg4) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return 0; } if ((*jenv)->GetArrayLength(jenv, jarg4) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return 0; } arg4 = &temp4; } { if (arg2 < 0) { { SWIG_JavaException(jenv, SWIG_ValueError, "Expected a non-negative value."); return 0; }; } } result = (uint8_t *)WebPDecodeRGBA((uint8_t const *)arg1,arg2,arg3,arg4); jresult = SWIG_JavaArrayOutSchar(jenv, result, FillMeInAsSizeCannotBeDeterminedAutomatically); SWIG_JavaArrayArgoutSchar(jenv, jarr1, arg1, jarg1); { jint jvalue = (jint)temp3; (*jenv)->SetIntArrayRegion(jenv, jarg3, 0, 1, &jvalue); } { jint jvalue = (jint)temp4; (*jenv)->SetIntArrayRegion(jenv, jarg4, 0, 1, &jvalue); } free(arg1); free(result); return jresult; }
gboolean load_image(const gchar *filename, gint32 *image_ID, GError **error) { gboolean status = FALSE; gchar *indata = NULL; gsize indatalen; gint width; gint height; WebPMux *mux = NULL; WebPData wp_data; uint32_t flags; uint8_t *outdata = NULL; #ifdef GIMP_2_9 /* Initialize GEGL */ gegl_init(NULL, NULL); #endif do { /* Attempt to read the file contents from disk */ if (g_file_get_contents(filename, &indata, &indatalen, error) == FALSE) { break; } /* Validate WebP data, grabbing the width and height */ if (!WebPGetInfo(indata, indatalen, &width, &height)) { break; } /* Create a WebPMux from the contents of the file */ wp_data.bytes = (uint8_t*)indata; wp_data.size = indatalen; mux = WebPMuxCreate(&wp_data, 1); if (mux == NULL) { break; } /* Retrieve the features present */ if (WebPMuxGetFeatures(mux, &flags) != WEBP_MUX_OK) { break; } /* TODO: decode the image in "chunks" or "tiles" */ /* TODO: check if an alpha channel is present */ /* Create the new image and associated layer */ *image_ID = gimp_image_new(width, height, GIMP_RGB); #ifdef WEBP_0_5 if (flags & ANIMATION_FLAG) { int frames, i; /* Retrieve the number of frames */ WebPMuxNumChunks(mux, WEBP_CHUNK_ANMF, &frames); /* Loop over each of the frames */ for (i = 0; i < frames; ++i) { WebPMuxFrameInfo frame = {0}; /* Retrieve the data for the frame */ if (WebPMuxGetFrame(mux, i, &frame) != WEBP_MUX_OK) { goto error; } /* Decode the frame */ outdata = WebPDecodeRGBA(frame.bitstream.bytes, frame.bitstream.size, &width, &height); /* Free the compressed data */ WebPDataClear(&frame.bitstream); if (!outdata) { goto error; } /* Create a layer for the frame */ char name[255]; snprintf(name, 255, "Frame %d", (i + 1)); if (create_layer(*image_ID, outdata, 0, (gchar*)name, width, height, frame.x_offset, frame.y_offset) == FALSE) { goto error; } } /* If all is well, jump *over* the error label - otherwise leave the loop and begin cleaning things up */ goto success; error: break; success: ; } else { #endif /* Attempt to decode the data as a WebP image */ outdata = WebPDecodeRGBA(indata, indatalen, &width, &height); if (!outdata) { break; } /* Create a single layer */ status = create_layer(*image_ID, outdata, 0, "Background", width, height, 0, 0); #ifdef WEBP_0_5 } #ifdef GIMP_2_9 /* Load a color profile if one was provided */ if (flags & ICCP_FLAG) { WebPData icc_profile; GimpColorProfile *profile; /* Load the ICC profile from the file */ WebPMuxGetChunk(mux, "ICCP", &icc_profile); /* Have Gimp load the color profile */ profile = gimp_color_profile_new_from_icc_profile( icc_profile.bytes, icc_profile.size, NULL); if (profile) { gimp_image_set_color_profile(image_ID, profile); g_object_unref(profile); } } #endif #endif /* Set the filename for the image */ gimp_image_set_filename(*image_ID, filename); } while(0); /* Delete the mux object */ if (mux) { WebPMuxDelete(mux); } /* Free the data read from disk */ if (indata) { g_free(indata); } return status; }
static int iwwebp_read_main(struct iwwebpreadcontext *rctx) { struct iw_image *img; int retval=0; void *webpimage=NULL; size_t webpimage_size=0; uint8_t* uncmpr_webp_pixels = NULL; int width, height; size_t npixels; int bytes_per_pixel; img = rctx->img; // TODO: This is really memory-inefficient. // Honestly, I just can't figure out libwebp. // It has several different ways to decode a webp image, but they don't // seem to add up to any way to do it without allocating at least one // more image's worth of memory than ought to be necessary. // It's like it expects you to know the width, height, and color format // of the image before that information has been read from the file. // Read the whole WebP file into a memory block. if(!iw_file_to_memory(rctx->ctx, rctx->iodescr, &webpimage, &webpimage_size)) { goto done; } // Have libwebp decode that memory block, to a memory block that // it allocates. width=height=0; uncmpr_webp_pixels = WebPDecodeRGBA(webpimage, (uint32_t)webpimage_size, &width, &height); if(!uncmpr_webp_pixels) goto done; if(!iw_check_image_dimensons(rctx->ctx,width,height)) goto done; npixels = ((size_t)width)*height; // Figure out if the image has transparency, etc. iwwebp_scan_pixels(rctx,uncmpr_webp_pixels,npixels); // Choose the color format to use for IW's internal source image. if(rctx->has_color) img->imgtype = rctx->has_transparency ? IW_IMGTYPE_RGBA : IW_IMGTYPE_RGB; else img->imgtype = rctx->has_transparency ? IW_IMGTYPE_GRAYA : IW_IMGTYPE_GRAY; img->width = width; img->height = height; img->bit_depth = 8; bytes_per_pixel = iw_imgtype_num_channels(img->imgtype); img->bpr = bytes_per_pixel * img->width; img->pixels = (unsigned char*)iw_malloc_large(rctx->ctx, img->bpr, img->height); if(!img->pixels) goto done; switch(img->imgtype) { case IW_IMGTYPE_GRAY: iwwebpr_convert_pixels_gray(rctx,(unsigned char*)uncmpr_webp_pixels,npixels); break; case IW_IMGTYPE_GRAYA: iwwebpr_convert_pixels_graya(rctx,(unsigned char*)uncmpr_webp_pixels,npixels); break; case IW_IMGTYPE_RGB: iwwebpr_convert_pixels_rgb(rctx,(unsigned char*)uncmpr_webp_pixels,npixels); break; default: iwwebpr_convert_pixels_rgba(rctx,(unsigned char*)uncmpr_webp_pixels,npixels); break; } retval=1; done: if(webpimage) iw_free(webpimage); // Caution: We must use the right free() function: the one that corresponds // to the malloc function that libwebp used. But we can't always be sure // how to do that. It depends on how libwebp was compiled. if(uncmpr_webp_pixels) free(uncmpr_webp_pixels); return retval; }