static void drawbmp(fz_context *ctx, fz_document *doc, fz_page *page, fz_display_list *list, int pagenum, fz_cookie *cookie) { float zoom; fz_matrix ctm; fz_irect ibounds; fz_rect bounds, tbounds; int w, h; fz_device *dev; HDC dc, dc_main; RECT rc; HBRUSH bg_brush; HBITMAP hbmp; BITMAPINFO bmi = { 0 }; int bmp_data_len; unsigned char *bmp_data; fz_bound_page(doc, page, &bounds); zoom = resolution / 72; fz_pre_scale(fz_rotate(&ctm, rotation), zoom, zoom); tbounds = bounds; fz_round_rect(&ibounds, fz_transform_rect(&tbounds, &ctm)); w = width; h = height; if (res_specified) { fz_round_rect(&ibounds, &tbounds); if (w && ibounds.x1 - ibounds.x0 <= w) w = 0; if (h && ibounds.y1 - ibounds.y0 <= h) h = 0; } if (w || h) { float scalex = w / (tbounds.x1 - tbounds.x0); float scaley = h / (tbounds.y1 - tbounds.y0); fz_matrix scale_mat; if (w == 0) scalex = fit ? 1.0f : scaley; if (h == 0) scaley = fit ? 1.0f : scalex; if (!fit) scalex = scaley = min(scalex, scaley); fz_concat(&ctm, &ctm, fz_scale(&scale_mat, scalex, scaley)); tbounds = bounds; fz_transform_rect(&tbounds, &ctm); } fz_round_rect(&ibounds, &tbounds); fz_rect_from_irect(&tbounds, &ibounds); w = ibounds.x1 - ibounds.x0; h = ibounds.y1 - ibounds.y0; dc_main = GetDC(NULL); dc = CreateCompatibleDC(dc_main); hbmp = CreateCompatibleBitmap(dc_main, w, h); DeleteObject(SelectObject(dc, hbmp)); SetRect(&rc, 0, 0, w, h); bg_brush = CreateSolidBrush(RGB(0xFF,0xFF,0xFF)); FillRect(dc, &rc, bg_brush); DeleteObject(bg_brush); dev = fz_new_gdiplus_device(ctx, dc, &tbounds); if (list) fz_run_display_list(list, dev, &ctm, &tbounds, cookie); else fz_run_page(doc, page, dev, &ctm, cookie); fz_free_device(dev); bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = output_format == OUT_TGA ? -h : h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = output_format == OUT_TGA ? 32 : 24; bmi.bmiHeader.biCompression = BI_RGB; bmp_data_len = output_format == OUT_TGA ? w * h * 4 : ((w * 3 + 3) / 4) * 4 * h; bmp_data = fz_malloc(ctx, bmp_data_len); if (!GetDIBits(dc, hbmp, 0, h, bmp_data, &bmi, DIB_RGB_COLORS)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot draw page %d in PDF file '%s'", pagenum, filename); DeleteDC(dc); ReleaseDC(NULL, dc_main); DeleteObject(hbmp); if (output) { char buf[512]; FILE *f; sprintf(buf, output, pagenum); f = fopen(buf, "wb"); if (!f) fz_throw(ctx, FZ_ERROR_GENERIC, "could not create raster file '%s'", buf); if (output_format == OUT_TGA) { fz_pixmap *pix = fz_new_pixmap_with_data(ctx, fz_device_bgr(ctx), w, h, bmp_data); fz_write_tga(ctx, pix, buf, 0); fz_drop_pixmap(ctx, pix); } else { BITMAPFILEHEADER bmpfh = { 0 }; static const int one = 1; if (!*(char *)&one) fz_throw(ctx, FZ_ERROR_GENERIC, "rendering to BMP is not supported on big-endian architectures"); bmpfh.bfType = MAKEWORD('B', 'M'); bmpfh.bfOffBits = sizeof(bmpfh) + sizeof(bmi); bmpfh.bfSize = bmpfh.bfOffBits + bmp_data_len; fwrite(&bmpfh, sizeof(bmpfh), 1, f); fwrite(&bmi, sizeof(bmi), 1, f); fwrite(bmp_data, 1, bmp_data_len, f); } fclose(f); } if (showmd5) { fz_pixmap *pix = fz_new_pixmap_with_data(ctx, fz_device_bgr(ctx), bmp_data_len / 4 / h, h, bmp_data); unsigned char digest[16]; int i; fz_md5_pixmap(pix, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); fz_drop_pixmap(ctx, pix); } fz_free(ctx, bmp_data); }
static void drawbmp(fz_context *ctx, fz_document *doc, fz_page *page, fz_display_list *list, int pagenum) { float zoom; fz_matrix ctm; fz_bbox bbox; fz_rect bounds, bounds2; int w, h; fz_device *dev; HDC dc, dc_main; RECT rc; HBRUSH bg_brush; HBITMAP hbmp; BITMAPINFO bmi = { 0 }; int bmp_data_len; char *bmp_data; bounds = fz_bound_page(doc, page); zoom = resolution / 72; ctm = fz_scale(zoom, zoom); ctm = fz_concat(ctm, fz_rotate(rotation)); bounds2 = fz_transform_rect(ctm, bounds); w = width; h = height; if (res_specified) { bbox = fz_round_rect(bounds2); if (w && bbox.x1 - bbox.x0 <= w) w = 0; if (h && bbox.y1 - bbox.y0 <= h) h = 0; } if (w || h) { float scalex = w / (bounds2.x1 - bounds2.x0); float scaley = h / (bounds2.y1 - bounds2.y0); if (w == 0) scalex = fit ? 1.0f : scaley; if (h == 0) scaley = fit ? 1.0f : scalex; if (!fit) scalex = scaley = min(scalex, scaley); ctm = fz_concat(ctm, fz_scale(scalex, scaley)); bounds2 = fz_transform_rect(ctm, bounds); } bbox = fz_round_rect(bounds2); w = bbox.x1 - bbox.x0; h = bbox.y1 - bbox.y0; dc_main = GetDC(NULL); dc = CreateCompatibleDC(dc_main); hbmp = CreateCompatibleBitmap(dc_main, w, h); DeleteObject(SelectObject(dc, hbmp)); SetRect(&rc, 0, 0, w, h); bg_brush = CreateSolidBrush(RGB(0xFF,0xFF,0xFF)); FillRect(dc, &rc, bg_brush); DeleteObject(bg_brush); dev = fz_new_gdiplus_device(ctx, dc, fz_rect_from_bbox(bbox)); if (list) fz_run_display_list(list, dev, ctm, fz_rect_from_bbox(bbox), NULL); else fz_run_page(doc, page, dev, ctm, NULL); fz_free_device(dev); 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; bmp_data_len = ((w * 3 + 3) / 4) * 4 * h; bmp_data = fz_malloc(ctx, bmp_data_len + 1); if (!GetDIBits(dc, hbmp, 0, h, bmp_data, &bmi, DIB_RGB_COLORS)) fz_throw(ctx, "cannot draw page %d in PDF file '%s'", pagenum, filename); DeleteDC(dc); ReleaseDC(NULL, dc_main); DeleteObject(hbmp); if (output) { char buf[512]; FILE *f; sprintf(buf, output, pagenum); f = fopen(buf, "wb"); if (!f) fz_throw(ctx, "could not create raster file '%s'", buf); if (strstr(output, ".bmp")) { BITMAPFILEHEADER bmpfh = { 0 }; static const int one = 1; if (!*(char *)&one) fz_throw(ctx, "rendering to BMP is not supported on big-endian architectures"); bmpfh.bfType = MAKEWORD('B', 'M'); bmpfh.bfOffBits = sizeof(bmpfh) + sizeof(bmi); bmpfh.bfSize = bmpfh.bfOffBits + bmp_data_len; fwrite(&bmpfh, sizeof(bmpfh), 1, f); fwrite(&bmi, sizeof(bmi), 1, f); fwrite(bmp_data, 1, bmp_data_len, f); } else { unsigned short width = w, height = h, k; fwrite("\0\0\x0A\0\0\0\0\0\0\0\0\0", 1, 12, f); putc(width & 0xFF, f); putc((width >> 8) & 0xFF, f); putc(height & 0xFF, f); putc((height >> 8) & 0xFF, f); fwrite("\x18\0", 1, 2, f); for (k = 0; k < height; k++) { int i, j; char *line = bmp_data + bmp_data_len / h * k; for (i = 0, j = 1; i < width; i += j, j = 1) { #define memeq3(a, b) (*(WORD *)(a) == *(WORD *)(b) && (a)[2] == (b)[2]) for (; i + j < width && j < 128 && memeq3(line + i * 3, line + (i + j) * 3); j++); if (j > 1) { putc(j - 1 + 128, f); fwrite(line + i * 3, 1, 3, f); } else { for (; i + j < width && j <= 128 && !memeq3(line + (i + j - 1) * 3, line + (i + j) * 3) != 0; j++); if (i + j < width || j > 128) j--; putc(j - 1, f); fwrite(line + i * 3, 1, j * 3, f); } #undef memeq3 } } fwrite("\0\0\0\0\0\0\0\0TRUEVISION-XFILE.\0", 1, 26, f); } fclose(f); } if (showmd5) { fz_pixmap *pix = fz_new_pixmap_with_data(ctx, fz_device_rgb, bmp_data_len / 4 / h, h, bmp_data); unsigned char digest[16]; int i; fz_md5_pixmap(pix, digest); printf(" "); for (i = 0; i < 16; i++) printf("%02x", digest[i]); fz_drop_pixmap(ctx, pix); } fz_free(ctx, bmp_data); }