void fz_free_shade_imp(fz_context *ctx, fz_storable *shade_) { fz_shade *shade = (fz_shade *)shade_; if (shade->colorspace) fz_drop_colorspace(ctx, shade->colorspace); if (shade->type == FZ_FUNCTION_BASED) fz_free(ctx, shade->u.f.fn_vals); fz_free_compressed_buffer(ctx, shade->buffer); fz_free(ctx, shade); }
static void pdf_free_image(fz_context *ctx, fz_storable *image_) { pdf_image *image = (pdf_image *)image_; if (image == NULL) return; fz_drop_pixmap(ctx, image->tile); fz_free_compressed_buffer(ctx, image->buffer); fz_drop_colorspace(ctx, image->base.colorspace); fz_drop_image(ctx, image->base.mask); fz_free(ctx, image); }
fz_image * fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer) { fz_compressed_buffer *bc = NULL; int w, h, xres, yres; fz_colorspace *cspace; int len = buffer->len; unsigned char *buf = buffer->data; fz_var(bc); fz_try(ctx) { if (len < 8) fz_throw(ctx, FZ_ERROR_GENERIC, "unknown image file format"); bc = fz_malloc_struct(ctx, fz_compressed_buffer); bc->buffer = fz_keep_buffer(ctx, buffer); if (buf[0] == 0xff && buf[1] == 0xd8) { bc->params.type = FZ_IMAGE_JPEG; bc->params.u.jpeg.color_transform = -1; fz_load_jpeg_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace); } else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0) { bc->params.type = FZ_IMAGE_PNG; fz_load_png_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace); } else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC) { bc->params.type = FZ_IMAGE_JXR; fz_load_jxr_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace); } else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0) { bc->params.type = FZ_IMAGE_TIFF; fz_load_tiff_info(ctx, buf, len, &w, &h, &xres, &yres, &cspace); } else fz_throw(ctx, FZ_ERROR_GENERIC, "unknown image file format"); } fz_catch(ctx) { fz_free_compressed_buffer(ctx, bc); fz_rethrow(ctx); } return fz_new_image(ctx, w, h, 8, cspace, xres, yres, 0, 0, NULL, NULL, bc, NULL); }
fz_image * fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask) { fz_image *image; assert(mask == NULL || mask->mask == NULL); fz_try(ctx) { image = fz_malloc_struct(ctx, fz_image); FZ_INIT_STORABLE(image, 1, fz_free_image); image->get_pixmap = fz_image_get_pixmap; image->w = w; image->h = h; image->xres = xres; image->yres = yres; image->bpc = bpc; image->n = (colorspace ? colorspace->n : 1); image->colorspace = colorspace; image->interpolate = interpolate; image->imagemask = imagemask; image->usecolorkey = (colorkey != NULL); if (colorkey) memcpy(image->colorkey, colorkey, sizeof(int)*image->n*2); if (decode) memcpy(image->decode, decode, sizeof(float)*image->n*2); else { float maxval = fz_colorspace_is_indexed(colorspace) ? (1 << bpc) - 1 : 1; int i; for (i = 0; i < image->n; i++) { image->decode[2*i] = 0; image->decode[2*i+1] = maxval; } } image->mask = mask; image->buffer = buffer; } fz_catch(ctx) { fz_free_compressed_buffer(ctx, buffer); fz_rethrow(ctx); } return image; }
static fz_image *pack_jp2(fz_context *ctx, const char *data, size_t len, SizeI size) { fz_compressed_buffer *buf = nullptr; fz_var(buf); fz_try(ctx) { buf = fz_malloc_struct(ctx, fz_compressed_buffer); buf->buffer = fz_new_buffer(ctx, (int)len); memcpy(buf->buffer->data, data, (buf->buffer->len = (int)len)); buf->params.type = FZ_IMAGE_JPX; } fz_catch(ctx) { fz_free_compressed_buffer(ctx, buf); fz_rethrow(ctx); } return fz_new_image(ctx, size.dx, size.dy, 8, fz_device_rgb(ctx), 96, 96, 0, 0, nullptr, nullptr, buf, nullptr); }
static fz_image *pack_jpeg(fz_context *ctx, const char *data, size_t len, SizeI size) { fz_compressed_buffer *buf = NULL; fz_var(buf); fz_try(ctx) { buf = fz_malloc_struct(ctx, fz_compressed_buffer); buf->buffer = fz_new_buffer(ctx, (int)len); memcpy(buf->buffer->data, data, (buf->buffer->len = (int)len)); buf->params.type = FZ_IMAGE_JPEG; buf->params.u.jpeg.color_transform = -1; } fz_catch(ctx) { fz_free_compressed_buffer(ctx, buf); fz_rethrow(ctx); } return fz_new_image(ctx, size.dx, size.dy, 8, fz_device_rgb(ctx), 96, 96, 0, 0, NULL, NULL, buf, NULL); }
static fz_image *render_to_pixmap(fz_context *ctx, HBITMAP hbmp, SizeI size) { int w = size.dx, h = size.dy; int stride = ((w * 3 + 3) / 4) * 4; unsigned char *data = (unsigned char *)fz_malloc(ctx, stride * h); BITMAPINFO bmi = { 0 }; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = -h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; HDC hDC = GetDC(nullptr); int res = GetDIBits(hDC, hbmp, 0, h, data, &bmi, DIB_RGB_COLORS); ReleaseDC(nullptr, hDC); if (!res) { fz_free(ctx, data); fz_throw(ctx, FZ_ERROR_GENERIC, "GetDIBits failed"); } // convert BGR with padding to RGB without padding unsigned char *out = data; bool is_grayscale = true; for (int y = 0; y < h; y++) { const unsigned char *in = data + y * stride; unsigned char green, blue; for (int x = 0; x < w; x++) { is_grayscale = is_grayscale && in[0] == in[1] && in[0] == in[2]; blue = *in++; green = *in++; *out++ = *in++; *out++ = green; *out++ = blue; } } // convert grayscale RGB to proper grayscale if (is_grayscale) { const unsigned char *in = out = data; for (int i = 0; i < w * h; i++) { *out++ = *in++; in += 2; } } fz_compressed_buffer *buf = nullptr; fz_var(buf); fz_try(ctx) { buf = fz_malloc_struct(ctx, fz_compressed_buffer); buf->buffer = fz_new_buffer(ctx, w * h * 4 + 10); buf->params.type = FZ_IMAGE_FLATE; buf->params.u.flate.predictor = 1; z_stream zstm = { 0 }; zstm.next_in = data; zstm.avail_in = out - data; zstm.next_out = buf->buffer->data; zstm.avail_out = buf->buffer->cap; res = deflateInit(&zstm, 9); if (res != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); res = deflate(&zstm, Z_FINISH); if (res != Z_STREAM_END) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); buf->buffer->len = zstm.total_out; res = deflateEnd(&zstm); if (res != Z_OK) fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res); } fz_always(ctx) { fz_free(ctx, data); } fz_catch(ctx) { fz_free_compressed_buffer(ctx, buf); fz_rethrow(ctx); } fz_colorspace *cs = is_grayscale ? fz_device_gray(ctx) : fz_device_rgb(ctx); return fz_new_image(ctx, w, h, 8, cs, 96, 96, 0, 0, nullptr, nullptr, buf, nullptr); }