Example #1
1
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;
}
Example #2
0
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)}};
}
Example #3
0
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);
}
Example #4
0
uint8_t* webpDecodeRGBA(
	const uint8_t* data, size_t data_size,
	int* width, int* height
) {
	return WebPDecodeRGBA(data, data_size, width, height);
}
Example #5
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   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);
}
Example #6
0
bool WebPImageReader::decode() {
    surface = (unsigned int *)WebPDecodeRGBA(source, length, NULL, NULL);
    return surface != NULL;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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;
}