size_t webpEncodeGray( const uint8_t* gray, int width, int height, int stride, float quality_factor, uint8_t** output ) { size_t output_size; uint8_t* rgb; int x, y; if((rgb = (uint8_t*)malloc(width*height*3)) == NULL) { return 0; } for(y = 0; y < height; ++y) { const uint8_t* src = gray + y*stride; uint8_t* dst = rgb + y*width*3; for(x = 0; x < width; ++x) { uint8_t v = *src++; *dst++ = v; *dst++ = v; *dst++ = v; } } output_size = WebPEncodeRGB(rgb, width, height, width*3, quality_factor, output); free(rgb); return output_size; }
PyObject* WebPEncodeRGB_wrapper(PyObject* self, PyObject* args) { PyBytesObject *rgb_string; int width; int height; int stride; float quality_factor; uint8_t *rgb; uint8_t *output; Py_ssize_t size; size_t ret_size; if (!PyArg_ParseTuple(args, "Siiif", &rgb_string, &width, &height, &stride, &quality_factor)) { Py_INCREF(Py_None); return Py_None; } PyBytes_AsStringAndSize((PyObject *) rgb_string, (char**)&rgb, &size); if (stride * height > size) { Py_INCREF(Py_None); return Py_None; } ret_size = WebPEncodeRGB(rgb, width, height, stride, quality_factor, &output); if (ret_size > 0) { PyObject *ret = PyBytes_FromStringAndSize((char*)output, ret_size); free(output); return ret; } Py_INCREF(Py_None); return Py_None; }
uint8_t* webpEncodeRGB( const uint8_t* rgb, int width, int height, int stride, float quality_factor, size_t* output_size ) { uint8_t* output = NULL; *output_size = WebPEncodeRGB(rgb, width, height, stride, quality_factor, &output); return output; }
static int iwwebp_write_main(struct iwwebpwritecontext *wctx) { struct iw_image *img; size_t ret; uint8_t *cmpr_webp_data = NULL; int retval=0; double quality; img = wctx->img; quality = iw_get_value_dbl(wctx->ctx,IW_VAL_WEBP_QUALITY); if(quality<0.0) { quality=80.0; // Default quality. } switch(img->imgtype) { case IW_IMGTYPE_GRAY: // IW requires encoders to support grayscale, but WebP doesn't (?) // support it. So, convert grayscale images to RGB. iwwebp_gray_to_rgb(wctx); // Allocates RGB image at wctx->tmppixels. if(!wctx->tmppixels) goto done; ret = WebPEncodeRGB(wctx->tmppixels, img->width, img->height, 3*img->width, (float)quality, &cmpr_webp_data); break; case IW_IMGTYPE_RGB: ret = WebPEncodeRGB(img->pixels, img->width, img->height, (int)img->bpr, (float)quality, &cmpr_webp_data); break; default: iw_seterror(wctx->ctx,iwwebp_get_string(wctx->ctx,iws_webp_enc_bad_imgtype),img->imgtype); goto done; } if(ret<1 || !cmpr_webp_data) { goto done; } iwwebp_write(wctx, cmpr_webp_data, ret); retval=1; done: if(cmpr_webp_data) free(cmpr_webp_data); if(wctx->tmppixels) iw_free(wctx->tmppixels); return 1; }
void convert_tiff_to_webp_gray(const char* file_name, const char* out_file_name) { TIFF* tif = TIFFOpen(file_name, "r"); if (tif) { uint32 w, h; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); uint32 imagelength; unsigned char gray_value; TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); tsize_t scanline = TIFFScanlineSize(tif); unsigned char *buf = (unsigned char*)_TIFFmalloc(scanline); unsigned char *result = (unsigned char*)malloc(3 * w * h + 1); int iterator = 0; for (uint32 row = 0; row < h; ++row) { TIFFReadScanline(tif, buf, row); for (uint32 col = 0; col < w * 3; col+=3) { gray_value = (unsigned char)(((float)buf[col] + (float)buf[col + 1] + (float)buf[col + 2]) / 3.0 + 0.5); result[iterator] = gray_value; result[iterator + 1] = gray_value; result[iterator + 2] = gray_value; iterator += 3; } } uint8_t* output; FILE *op_file; size_t d_size; d_size = WebPEncodeRGB(result, w, h, 3 * w, 100.0, &output); op_file=fopen(out_file_name,"wb"); fwrite(output,1,(int)d_size, op_file); free(result); _TIFFfree(buf); TIFFClose(tif); } else { printf("I can't open the TIF file\n"); } }
PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args) { int width; int height; float quality_factor; uint8_t *rgb; uint8_t *output; char *mode; Py_ssize_t size; size_t ret_size; if (!PyArg_ParseTuple(args, "s#iifs",(char**)&rgb, &size, &width, &height, &quality_factor, &mode)) { Py_RETURN_NONE; } if (strcmp(mode, "RGBA")==0){ if (size < width * height * 4){ Py_RETURN_NONE; } ret_size = WebPEncodeRGBA(rgb, width, height, 4* width, quality_factor, &output); } else if (strcmp(mode, "RGB")==0){ if (size < width * height * 3){ Py_RETURN_NONE; } ret_size = WebPEncodeRGB(rgb, width, height, 3* width, quality_factor, &output); } else { Py_RETURN_NONE; } if (ret_size > 0) { PyObject *ret = PyBytes_FromStringAndSize((char*)output, ret_size); free(output); return ret; } Py_RETURN_NONE; }
static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) { ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), PoolVector<uint8_t>()); Ref<Image> img = p_image->duplicate(); if (img->detect_alpha()) img->convert(Image::FORMAT_RGBA8); else img->convert(Image::FORMAT_RGB8); Size2 s(img->get_width(), img->get_height()); PoolVector<uint8_t> data = img->get_data(); PoolVector<uint8_t>::Read r = data.read(); uint8_t *dst_buff = NULL; size_t dst_size = 0; if (img->get_format() == Image::FORMAT_RGB8) { dst_size = WebPEncodeRGB(r.ptr(), s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff); } else { dst_size = WebPEncodeRGBA(r.ptr(), s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff); } ERR_FAIL_COND_V(dst_size == 0, PoolVector<uint8_t>()); PoolVector<uint8_t> dst; dst.resize(4 + dst_size); PoolVector<uint8_t>::Write w = dst.write(); w[0] = 'W'; w[1] = 'E'; w[2] = 'B'; w[3] = 'P'; copymem(&w[4], dst_buff, dst_size); free(dst_buff); w = PoolVector<uint8_t>::Write(); return dst; }
size_t webpEncodeRGB( const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output ) { return WebPEncodeRGB(rgb, width, height, stride, quality_factor, output); }
PyObject* WebPEncode_wrapper(PyObject* self, PyObject* args) { int width; int height; int lossless; float quality_factor; uint8_t *rgb; uint8_t *icc_bytes; uint8_t *exif_bytes; uint8_t *output; char *mode; Py_ssize_t size; Py_ssize_t icc_size; Py_ssize_t exif_size; size_t ret_size; if (!PyArg_ParseTuple(args, "s#iiifss#s#", (char**)&rgb, &size, &width, &height, &lossless, &quality_factor, &mode, &icc_bytes, &icc_size, &exif_bytes, &exif_size)) { Py_RETURN_NONE; } if (strcmp(mode, "RGBA")==0){ if (size < width * height * 4){ Py_RETURN_NONE; } if (lossless) { ret_size = WebPEncodeLosslessRGBA(rgb, width, height, 4* width, &output); } else { ret_size = WebPEncodeRGBA(rgb, width, height, 4* width, quality_factor, &output); } } else if (strcmp(mode, "RGB")==0){ if (size < width * height * 3){ Py_RETURN_NONE; } if (lossless) { ret_size = WebPEncodeLosslessRGB(rgb, width, height, 3* width, &output); } else { ret_size = WebPEncodeRGB(rgb, width, height, 3* width, quality_factor, &output); } } else { Py_RETURN_NONE; } #ifndef HAVE_WEBPMUX if (ret_size > 0) { PyObject *ret = PyBytes_FromStringAndSize((char*)output, ret_size); free(output); return ret; } #else { /* I want to truncate the *_size items that get passed into webp data. Pypy2.1.0 had some issues where the Py_ssize_t items had data in the upper byte. (Not sure why, it shouldn't have been there) */ int i_icc_size = (int)icc_size; int i_exif_size = (int)exif_size; WebPData output_data = {0}; WebPData image = { output, ret_size }; WebPData icc_profile = { icc_bytes, i_icc_size }; WebPData exif = { exif_bytes, i_exif_size }; WebPMuxError err; int dbg = 0; int copy_data = 0; // value 1 indicates given data WILL be copied to the mux // and value 0 indicates data will NOT be copied. WebPMux* mux = WebPMuxNew(); WebPMuxSetImage(mux, &image, copy_data); if (dbg) { /* was getting %ld icc_size == 0, icc_size>0 was true */ fprintf(stderr, "icc size %d, %d \n", i_icc_size, i_icc_size > 0); } if (i_icc_size > 0) { if (dbg) { fprintf (stderr, "Adding ICC Profile\n"); } err = WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data); if (dbg && err == WEBP_MUX_INVALID_ARGUMENT) { fprintf(stderr, "Invalid ICC Argument\n"); } else if (dbg && err == WEBP_MUX_MEMORY_ERROR) { fprintf(stderr, "ICC Memory Error\n"); } } if (dbg) { fprintf(stderr, "exif size %d \n", i_exif_size); } if (i_exif_size > 0) { if (dbg){ fprintf (stderr, "Adding Exif Data\n"); } err = WebPMuxSetChunk(mux, "EXIF", &exif, copy_data); if (dbg && err == WEBP_MUX_INVALID_ARGUMENT) { fprintf(stderr, "Invalid Exif Argument\n"); } else if (dbg && err == WEBP_MUX_MEMORY_ERROR) { fprintf(stderr, "Exif Memory Error\n"); } } WebPMuxAssemble(mux, &output_data); WebPMuxDelete(mux); free(output); ret_size = output_data.size; if (ret_size > 0) { PyObject *ret = PyBytes_FromStringAndSize((char*)output_data.bytes, ret_size); WebPDataClear(&output_data); return ret; } } #endif Py_RETURN_NONE; }
int ImagingWebPEncode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) { WEBPCONTEXT* context = (WEBPCONTEXT*) state->context; UINT8* buffer; UINT8* ptr; int y, stride; float quality = 75.0F; if (!state->state) { /* copy image contents to packed buffer and compress it */ stride = state->xsize * 3; buffer = malloc(im->ysize * stride); if (!buffer) { state->errcode = IMAGING_CODEC_MEMORY; return -1; } for (ptr = buffer, y = 0; y < state->ysize; ptr += stride, y++) { state->shuffle(ptr, (UINT8*) im->image[y + state->yoff] + state->xoff * im->pixelsize, state->xsize); } if (context->quality > 0) quality = (float) context->quality; context->output_size = WebPEncodeRGB(buffer, state->xsize, state->ysize, stride, quality, &context->output_data); free(buffer); if (!context->output_size) { state->errcode = IMAGING_CODEC_BROKEN; return -1; } state->state++; /* keep a pointer to the full buffer */ context->output_buffer = context->output_data; } if (context->output_size < bytes) { /* copy remaining part to output buffer */ memcpy(buf, context->output_data, context->output_size); state->errcode = IMAGING_CODEC_END; free(context->output_buffer); return context->output_size; } else { /* not enough space; fill the buffer and try again next time */ memcpy(buf, context->output_data, bytes); context->output_data += bytes; context->output_size -= bytes; return bytes; } }