diff options
Diffstat (limited to 'devices/gdevpdfimg.c')
-rw-r--r-- | devices/gdevpdfimg.c | 241 |
1 files changed, 125 insertions, 116 deletions
diff --git a/devices/gdevpdfimg.c b/devices/gdevpdfimg.c index 998574c8..313d714f 100644 --- a/devices/gdevpdfimg.c +++ b/devices/gdevpdfimg.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2019 Artifex Software, Inc. +/* Copyright (C) 2001-2020 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -30,6 +30,8 @@ #include "gsicc_cache.h" #include "sjpeg.h" +#include "gdevpdfimg.h" + #define COMPRESSION_NONE 1 /* dump mode */ #define COMPRESSION_LZW 2 /* Lempel-Ziv & Welch */ #define COMPRESSION_FLATE 3 @@ -48,58 +50,9 @@ static struct compression_string { { 0, NULL } }; -int pdf_image_open(gx_device *pdev); int PCLm_open(gx_device *pdev); -int pdf_image_close(gx_device * pdev); int PCLm_close(gx_device * pdev); -int pdf_image_put_params_downscale(gx_device * dev, gs_param_list * plist); -int pdf_image_put_params_downscale_cmyk(gx_device * dev, gs_param_list * plist); -int pdf_image_put_params_downscale_cmyk_ets(gx_device * dev, gs_param_list * plist); -int pdf_image_get_params_downscale(gx_device * dev, gs_param_list * plist); -int pdf_image_get_params_downscale_cmyk(gx_device * dev, gs_param_list * plist); -int pdf_image_get_params_downscale_cmyk_ets(gx_device * dev, gs_param_list * plist); - -typedef struct pdfimage_page_s { - int ImageObjectNumber; - gs_offset_t ImageOffset;int LengthObjectNumber; - gs_offset_t LengthOffset; - int PageStreamObjectNumber; - gs_offset_t PageStreamOffset; - int PageDictObjectNumber; - gs_offset_t PageDictOffset; - void *next; -} pdfimage_page; - -typedef struct PCLm_temp_file_s { - char file_name[gp_file_name_sizeof]; - gp_file *file; - stream *strm; - stream *save; - byte *strm_buf; -} PCLm_temp_file_t; - -typedef struct gx_device_pdf_image_s { - gx_device_common; - gx_prn_device_common; - unsigned char Compression; - gx_downscaler_params downscale; - int StripHeight; - float QFactor; - int JPEGQ; - gsicc_link_t *icclink; - stream *strm; - byte *strm_buf; - int NumPages; - gs_offset_t RootOffset; - gs_offset_t PagesOffset; - gs_offset_t xrefOffset; - pdfimage_page *Pages; - PCLm_temp_file_t xref_stream; - PCLm_temp_file_t temp_stream; - int NextObject; -} gx_device_pdf_image; - -static dev_proc_print_page(pdf_image_print_page); + /* ------ The pdfimage8 device ------ */ @@ -268,7 +221,7 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, &rendering_params); } else { pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[0], profile_struct->postren_profile, + profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile, &rendering_params); } if (pdf_dev->icclink == NULL) { @@ -291,11 +244,11 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, } pdf_dev->strm_buf = gs_alloc_bytes(pdf_dev->memory->non_gc_memory, pdf_dev->width * (pdf_dev->color_info.depth / 8), "pdfimage_open_temp_stream(strm_buf)"); - if (pdf_dev->strm_buf == 0) { + if (pdf_dev->strm_buf == NULL) { pdf_dev->strm->file = NULL; /* Don't close underlying file when we free the stream */ gs_free_object(pdf_dev->memory->non_gc_memory, pdf_dev->strm, "pdfimage_open_temp_stream(strm)"); - pdf_dev->strm = 0; + pdf_dev->strm = NULL; gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); return_error(gs_error_VMerror); } @@ -303,6 +256,20 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, stream_puts(pdf_dev->strm, "%PDF-1.3\n"); stream_puts(pdf_dev->strm, "%\307\354\217\242\n"); + + if (pdf_dev->ocr.file_init) { + code = pdf_dev->ocr.file_init(pdf_dev); + if (code < 0) { + gs_free_object(pdf_dev->memory->non_gc_memory, pdf_dev->strm_buf, "pdfimage_open_temp_stream(strm_buf)"); + pdf_dev->strm->file = NULL; /* Don't close underlying file when we free the stream */ + gs_free_object(pdf_dev->memory->non_gc_memory, pdf_dev->strm, + "pdfimage_open_temp_stream(strm)"); + pdf_dev->strm = NULL; + gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page"); + return code; + } + } + pdfimage_write_args_comment(pdf_dev, pdf_dev->strm); pdf_dev->Pages = page; } else { @@ -311,7 +278,7 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev, current = current->next; current->next = page; } - page->ImageObjectNumber = (pdf_dev->NumPages * 4) + 3; + page->ImageObjectNumber = (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects; page->LengthObjectNumber = page->ImageObjectNumber + 1; page->PageStreamObjectNumber = page->LengthObjectNumber + 1; page->PageDictObjectNumber = page->PageStreamObjectNumber + 1; @@ -449,19 +416,19 @@ encode(gx_device *pdev, stream **s, const stream_template *t, gs_memory_t *mem) } static int -pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, - int mfs, int bpc, int num_comps, - int trap_w, int trap_h, const int *trap_order, - int ets) +pdf_image_downscale_and_print_page(gx_device_printer *dev, + gx_downscaler_params *params, + int bpc, int num_comps) { gx_device_pdf_image *const pdf_dev = (gx_device_pdf_image *)dev; int code = 0; byte *data = NULL; int size = gdev_mem_bytes_per_scan_line((gx_device *)dev); - int max_size =size; + int max_size = size; int row; - int height = dev->height/factor; - int width = dev->width/factor; + int factor = params->downscale_factor; + int height = gx_downscaler_scale(dev->height, factor); + int width = gx_downscaler_scale(dev->width, factor); gx_downscaler_t ds; gs_offset_t stream_pos = 0; pdfimage_page *page = pdf_dev->Pages; @@ -474,24 +441,23 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, while(page->next) page = page->next; - if (num_comps == 4) { - if (pdf_dev->icclink == NULL) { - code = gx_downscaler_init_trapped_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ trap_w, trap_h, trap_order, ets); - } else { - code = gx_downscaler_init_trapped_cm_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ trap_w, trap_h, trap_order, - pdf_image_chunky_post_cm, pdf_dev->icclink, pdf_dev->icclink->num_output, ets); - } + if (num_comps != 4) + params->trap_w = params->trap_h = 0; + if (pdf_dev->icclink == NULL) { + code = gx_downscaler_init(&ds, (gx_device *)dev, + 8, bpc, num_comps, + params, + NULL, /*&fax_adjusted_width*/ + 0 /*aw*/); } else { - if (pdf_dev->icclink == NULL) { - code = gx_downscaler_init_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ ets); - } else { - code = gx_downscaler_init_cm_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ pdf_image_chunky_post_cm, pdf_dev->icclink, - pdf_dev->icclink->num_output, ets); - } + code = gx_downscaler_init_cm(&ds, (gx_device *)dev, + 8, bpc, num_comps, + params, + NULL, /*&fax_adjusted_width*/ + 0, /*aw*/ + pdf_image_chunky_post_cm, + pdf_dev->icclink, + pdf_dev->icclink->num_output); } if (code < 0) return code; @@ -502,6 +468,16 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, return_error(gs_error_VMerror); } + if (pdf_dev->ocr.begin_page) { + code = pdf_dev->ocr.begin_page(pdf_dev, width, height, num_comps*8); + if (code < 0) + { + gs_free_object(dev->memory, data, "pdf_image_print_page(data)"); + gx_downscaler_fin(&ds); + return code; + } + } + pprintd1(pdf_dev->strm, "%d 0 obj\n", page->ImageObjectNumber); pprintd1(pdf_dev->strm, "<<\n/Length %d 0 R\n", page->LengthObjectNumber); stream_puts(pdf_dev->strm, "/Subtype /Image\n"); @@ -558,13 +534,15 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, code = gx_downscaler_getbits(&ds, data, row); if (code < 0) break; + if (pdf_dev->ocr.line) + pdf_dev->ocr.line(pdf_dev, data); stream_write(pdf_dev->strm, data, width * num_comps); } if (code < 0) { gs_free_object(dev->memory, data, "pdf_image_print_page(data)"); gx_downscaler_fin(&ds); - return code;; + return code; } switch(pdf_dev->Compression) { @@ -588,9 +566,26 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, page->PageStreamOffset = stell(pdf_dev->strm); pprintd1(pdf_dev->strm, "%d 0 obj\n", page->PageStreamObjectNumber); - gs_sprintf(Buffer, "%f 0 0 %f 0 0 cm\n/Im1 Do", (width / (pdf_dev->HWResolution[0] / 72)) * factor, (height / (pdf_dev->HWResolution[1] / 72)) * factor); - pprintd1(pdf_dev->strm, "<<\n/Length %d\n>>\nstream\n", strlen(Buffer)); - stream_puts(pdf_dev->strm, Buffer); + stream_puts(pdf_dev->strm, "<<\n/Filter/FlateDecode/Length \n>>\nstream\n"); + stream_pos = stell(pdf_dev->strm); + encode((gx_device *)pdf_dev, &pdf_dev->strm, &s_zlibE_template, pdf_dev->memory->non_gc_memory); + if (pdf_dev->ocr.end_page) + stream_puts(pdf_dev->strm, "q\n"); + pprintd2(pdf_dev->strm, "%d 0 0 %d 0 0 cm\n/Im1 Do", + (int)((width / (pdf_dev->HWResolution[0] / 72)) * factor), + (int)((height / (pdf_dev->HWResolution[1] / 72)) * factor)); + if (pdf_dev->ocr.end_page) { + stream_puts(pdf_dev->strm, "\nQ"); + pdf_dev->ocr.end_page(pdf_dev); + } + s_close_filters(&pdf_dev->strm, s); + { + gs_offset_t pos = stell(pdf_dev->strm); + gs_offset_t len = pos - stream_pos; + sseek(pdf_dev->strm, stream_pos - 21); + pprintd1(pdf_dev->strm, "%d", (int)len); + sseek(pdf_dev->strm, pos); + } stream_puts(pdf_dev->strm, "\nendstream\nendobj\n"); page->PageDictOffset = stell(pdf_dev->strm); @@ -599,8 +594,10 @@ pdf_image_downscale_and_print_page(gx_device_printer *dev, int factor, stream_puts(pdf_dev->strm, "/Type /Page\n/Parent 2 0 R\n"); gs_sprintf(Buffer, "/MediaBox [0 0 %f %f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72); stream_puts(pdf_dev->strm, Buffer); - pprintd1(pdf_dev->strm, "/Resources <<\n/XObject <<\n/Im1 %d 0 R\n>>\n>>\n>>\n", page->ImageObjectNumber); - stream_puts(pdf_dev->strm, "endobj\n"); + pprintd1(pdf_dev->strm, "/Resources <<\n/XObject <<\n/Im1 %d 0 R\n>>\n", page->ImageObjectNumber); + if (pdf_dev->ocr.file_init) + stream_puts(pdf_dev->strm, "/Font <<\n/Ft0 3 0 R\n>>\n"); + stream_puts(pdf_dev->strm, ">>\n>>\nendobj\n"); gx_downscaler_fin(&ds); gs_free_object(dev->memory, data, "pdf_image_print_page(data)"); @@ -703,10 +700,11 @@ static void write_xref_entry (stream *s, gs_offset_t Offset) static void pdf_store_default_Producer(char *buf) { - if ((gs_revision % 100) == 0) - gs_sprintf(buf, "(%s %1.1f)", gs_product, gs_revision / 100.0); - else - gs_sprintf(buf, "(%s %1.2f)", gs_product, gs_revision / 100.0); + int major = (int)(gs_revision / 1000); + int minor = (int)(gs_revision - (major * 1000)) / 10; + int patch = gs_revision % 10; + + gs_sprintf(buf, "(%s %d.%02d.%d)", gs_product, major, minor, patch); } static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm) @@ -761,9 +759,16 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm) if (PCLm) pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", pdf_dev->NextObject); else - pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", (pdf_dev->NumPages * 4) + 3); + pprintd1(pdf_dev->strm, "xref\n0 %d\n0000000000 65536 f \n", (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects); write_xref_entry(pdf_dev->strm, pdf_dev->RootOffset); write_xref_entry(pdf_dev->strm, pdf_dev->PagesOffset); + if (pdf_dev->ocr.file_objects) { + int i; + + for (i = 0; i < OCR_MAX_FILE_OBJECTS; i++) + if (pdf_dev->ocr.file_object_offset[i]) + write_xref_entry(pdf_dev->strm, pdf_dev->ocr.file_object_offset[i]); + } if (!PCLm) { page = pdf_dev->Pages; @@ -774,7 +779,7 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm) write_xref_entry(pdf_dev->strm, page->PageDictOffset); page = page->next; } - pprintd1(pdf_dev->strm, "trailer\n<<\n/Size %d\n/Root 1 0 R\n/ID [", (pdf_dev->NumPages * 4) + 3); + pprintd1(pdf_dev->strm, "trailer\n<<\n/Size %d\n/Root 1 0 R\n/ID [", (pdf_dev->NumPages * 4) + 3 + pdf_dev->ocr.file_objects); pdf_compute_fileID(pdf_dev, fileID, CreationDate, Title, Producer); write_fileID(pdf_dev->strm, (const byte *)&fileID, 16); write_fileID(pdf_dev->strm, (const byte *)&fileID, 16); @@ -844,7 +849,7 @@ static int pdf_image_finish_file(gx_device_pdf_image *pdf_dev, int PCLm) return 0; } -static int +int pdf_image_print_page(gx_device_printer * pdev, gp_file * file) { gx_device_pdf_image *const pdf_dev = (gx_device_pdf_image *)pdev; @@ -857,11 +862,9 @@ pdf_image_print_page(gx_device_printer * pdev, gp_file * file) return code; code = pdf_image_downscale_and_print_page(pdev, - pdf_dev->downscale.downscale_factor, - pdf_dev->downscale.min_feature_size, - 8, pdf_dev->color_info.num_components, - 0, 0, NULL, - pdf_dev->downscale.ets); + &pdf_dev->downscale, + 8, + pdf_dev->color_info.num_components); if (code < 0) return code; @@ -908,6 +911,7 @@ pdf_image_open(gx_device *pdev) } if (ppdev->OpenOutputFile) code = gdev_prn_open_printer_seekable(pdev, 1, true); + return code; } @@ -1209,6 +1213,7 @@ PCLm_open(gx_device *pdev) while(pdev->child) pdev = pdev->child; + memset(&ppdev->ocr, 0, sizeof(ppdev->ocr)); ppdev->file = NULL; ppdev->Pages = NULL; ppdev->NumPages = 0; @@ -1280,7 +1285,7 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev, &rendering_params); } else { pdf_dev->icclink = gsicc_alloc_link_dev(pdev->memory, - profile_struct->device_profile[0], profile_struct->postren_profile, + profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], profile_struct->postren_profile, &rendering_params); } if (pdf_dev->icclink == NULL) { @@ -1331,19 +1336,19 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev, } static int -PCLm_downscale_and_print_page(gx_device_printer *dev, int factor, - int mfs, int bpc, int num_comps, - int trap_w, int trap_h, const int *trap_order, - int ets) +PCLm_downscale_and_print_page(gx_device_printer *dev, + int bpc, int num_comps) { gx_device_pdf_image *const pdf_dev = (gx_device_pdf_image *)dev; int code = 0; uint Read; byte *data = NULL; int size = gdev_mem_bytes_per_scan_line((gx_device *)dev); - int max_size =size; + int max_size = size; int row, NumStrips; double StripDecrement; + const gx_downscaler_params *params = &pdf_dev->downscale; + int factor = params->downscale_factor; int height = dev->height/factor; int width = dev->width/factor; gx_downscaler_t ds; @@ -1358,12 +1363,20 @@ PCLm_downscale_and_print_page(gx_device_printer *dev, int factor, page = page->next; if (pdf_dev->icclink == NULL) { - code = gx_downscaler_init_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ ets); + code = gx_downscaler_init(&ds, (gx_device *)dev, + 8, bpc, num_comps, + params, + NULL, /*&fax_adjusted_width*/ + 0 /*aw*/); } else { - code = gx_downscaler_init_cm_ets(&ds, (gx_device *)dev, 8, bpc, num_comps, - factor, mfs, NULL, /*&fax_adjusted_width*/ 0, /*aw*/ pdf_image_chunky_post_cm, pdf_dev->icclink, - pdf_dev->icclink->num_output, ets); + code = gx_downscaler_init_cm(&ds, (gx_device *)dev, + 8, bpc, num_comps, + params, + NULL, /*&fax_adjusted_width*/ + 0, /*aw*/ + pdf_image_chunky_post_cm, + pdf_dev->icclink, + pdf_dev->icclink->num_output); } if (code < 0) return code; @@ -1386,7 +1399,7 @@ PCLm_downscale_and_print_page(gx_device_printer *dev, int factor, pprintd1(pdf_dev->strm, "%d 0 obj\n", page->PageDictObjectNumber); pprintd1(pdf_dev->strm, "<<\n/Contents %d 0 R\n", page->PageStreamObjectNumber); stream_puts(pdf_dev->strm, "/Type /Page\n/Parent 2 0 R\n"); - gs_sprintf(Buffer, "/MediaBox [0 0 %f %f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72); + gs_sprintf(Buffer, "/MediaBox [0 0 %.3f %.3f]\n", ((double)pdf_dev->width / pdf_dev->HWResolution[0]) * 72, ((double)pdf_dev->height / pdf_dev->HWResolution[1]) * 72); stream_puts(pdf_dev->strm, Buffer); stream_puts(pdf_dev->strm, "/Resources <<\n/XObject <<\n"); @@ -1405,9 +1418,9 @@ PCLm_downscale_and_print_page(gx_device_printer *dev, int factor, double adjusted; adjusted = height - (row * pdf_dev->StripHeight); adjusted = adjusted / (pdf_dev->HWResolution[1] / (factor * 72)); - gs_sprintf(Buffer, "%f 0 0 %f 0 0 cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, adjusted, row); + gs_sprintf(Buffer, "%.3f 0 0 %.3f 0 0 cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, adjusted, row); } else - gs_sprintf(Buffer, "%f 0 0 %f 0 %f cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, StripDecrement, ((height / (pdf_dev->HWResolution[1] / 72)) * factor) - (StripDecrement * (row + 1)), row); + gs_sprintf(Buffer, "%.3f 0 0 %.3f 0 %f cm\n/Im%d Do Q\n", (width / (pdf_dev->HWResolution[0] / 72)) * factor, StripDecrement, ((height / (pdf_dev->HWResolution[1] / 72)) * factor) - (StripDecrement * (row + 1)), row); stream_puts(pdf_dev->temp_stream.strm, Buffer); pprintd2(pdf_dev->strm, "/Im%d %d 0 R\n", row, page->ImageObjectNumber + (row * 2)); } @@ -1660,11 +1673,7 @@ PCLm_print_page(gx_device_printer * pdev, gp_file * file) return code; code = PCLm_downscale_and_print_page(pdev, - pdf_dev->downscale.downscale_factor, - pdf_dev->downscale.min_feature_size, - 8, pdf_dev->color_info.num_components, - 0, 0, NULL, - pdf_dev->downscale.ets); + 8, pdf_dev->color_info.num_components); if (code < 0) return code; |