diff --git a/filter/pdftoraster.cxx b/filter/pdftoraster.cxx index e8af184f..fd0736b3 100755 --- a/filter/pdftoraster.cxx +++ b/filter/pdftoraster.cxx @@ -49,12 +49,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include -#include -#include -#include -#include -#include -#include +#include "fpdfview.h" +#include "fpdf_edit.h" +#include "cpp/fpdf_scopers.h" #ifdef USE_LCMS1 #include #define cmsColorSpaceSignature icColorSpaceSignature @@ -120,6 +117,7 @@ namespace { bool swap_margin_x = false; bool swap_margin_y = false; bool allocLineBuf = false; + bool cupsManualCopies = true; ConvertLineFunc convertLineOdd; ConvertLineFunc convertLineEven; ConvertCSpaceFunc convertCSpace; @@ -374,6 +372,12 @@ static void parseOpts(int argc, char **argv) renderingIntent = INTENT_ABSOLUTE_COLORIMETRIC; } } + attr = ppdFindAttr(ppd,"cupsManualCopies",NULL); + if (attr != NULL && attr->value != NULL) { + if (strcasecmp(attr->value,"true") != 0) { + cupsManualCopies = false; + } + } if (header.Duplex) { /* analyze options relevant to Duplex */ const char *backside = ""; @@ -1551,7 +1555,7 @@ static unsigned char *removeAlpha(unsigned char *src, unsigned char *dst, unsign return temp; } -static void writePageImage(cups_raster_t *raster, poppler::document *doc, +static void writePageImage(cups_raster_t *raster, FPDF_DOCUMENT doc, int pageNo) { ConvertLineFunc convertLine; @@ -1559,36 +1563,37 @@ static void writePageImage(cups_raster_t *raster, poppler::document *doc, unsigned char *dp; unsigned int rowsize; - poppler::page *current_page =doc->create_page(pageNo-1); - poppler::page_renderer pr; - pr.set_render_hint(poppler::page_renderer::antialiasing, true); - pr.set_render_hint(poppler::page_renderer::text_antialiasing, true); + FPDF_PAGE current_page = FPDF_LoadPage(doc, pageNo -1); unsigned char *colordata,*newdata,*graydata,*onebitdata; unsigned int pixel_count; - poppler::image im; + int alpha = FPDFPage_HasTransparency(current_page) ? 1 : 0; + ScopedFPDFBitmap bitmap(FPDFBitmap_Create(header.cupsWidth, header.cupsHeight, alpha)); + FPDFBitmap_FillRect(bitmap.get(), 0, 0, header.cupsWidth, header.cupsHeight, 0xFFFFFFFF); //render the page according to the colourspace and generate the requried data switch (header.cupsColorSpace) { case CUPS_CSPACE_W://gray case CUPS_CSPACE_K://black case CUPS_CSPACE_SW://sgray if(header.cupsBitsPerColor==1){ //special case for 1-bit colorspaces - im = pr.render_page(current_page,header.HWResolution[0],header.HWResolution[1],bitmapoffset[0],bitmapoffset[1],bytesPerLine*8,header.cupsHeight); - newdata = (unsigned char *)malloc(sizeof(char)*3*im.width()*im.height()); - newdata = removeAlpha((unsigned char *)im.const_data(),newdata,im.width(),im.height()); - graydata=(unsigned char *)malloc(sizeof(char)*im.width()*im.height()); - cupsImageRGBToWhite(newdata,graydata,im.width()*im.height()); - onebitdata=(unsigned char *)malloc(sizeof(char)*bytesPerLine*im.height()); - onebitpixel(graydata,onebitdata,im.width(),im.height()); + FPDF_RenderPageBitmap(bitmap.get(), current_page, bitmapoffset[0], bitmapoffset[1], bytesPerLine*8, header.cupsHeight, 0, 0); + void *buffer = FPDFBitmap_GetBuffer(bitmap.get()); + newdata = (unsigned char *)malloc(sizeof(char)*3*header.cupsWidth*header.cupsHeight); + newdata = removeAlpha((unsigned char *)buffer, newdata, header.cupsWidth, header.cupsHeight); + graydata=(unsigned char *)malloc(sizeof(char)*header.cupsWidth*header.cupsHeight); + cupsImageRGBToWhite(newdata,graydata,header.cupsWidth*header.cupsHeight); + onebitdata=(unsigned char *)malloc(sizeof(char)*bytesPerLine*header.cupsHeight); + onebitpixel(graydata,onebitdata,header.cupsWidth, header.cupsHeight); colordata=onebitdata; rowsize=bytesPerLine; } else{ - im = pr.render_page(current_page,header.HWResolution[0],header.HWResolution[1],bitmapoffset[0],bitmapoffset[1],header.cupsWidth,header.cupsHeight); - newdata = (unsigned char *)malloc(sizeof(char)*3*im.width()*im.height()); - newdata = removeAlpha((unsigned char *)im.const_data(),newdata,im.width(),im.height()); - pixel_count=im.width()*im.height(); - graydata=(unsigned char *)malloc(sizeof(char)*im.width()*im.height()); + FPDF_RenderPageBitmap(bitmap.get(), current_page, bitmapoffset[0], bitmapoffset[1], header.cupsWidth, header.cupsHeight, 0, 0); + void *buffer = FPDFBitmap_GetBuffer(bitmap.get()); + newdata = (unsigned char *)malloc(sizeof(char)*3*header.cupsWidth*header.cupsHeight); + newdata = removeAlpha((unsigned char *)buffer, newdata, header.cupsWidth, header.cupsHeight); + pixel_count=header.cupsWidth * header.cupsHeight; + graydata=(unsigned char *)malloc(sizeof(char)*header.cupsWidth*header.cupsHeight); cupsImageRGBToWhite(newdata,graydata,pixel_count); colordata=graydata; rowsize=header.cupsWidth; @@ -1602,10 +1607,15 @@ static void writePageImage(cups_raster_t *raster, poppler::document *doc, case CUPS_CSPACE_CMY: case CUPS_CSPACE_RGBW: default: - im = pr.render_page(current_page,header.HWResolution[0],header.HWResolution[1],bitmapoffset[0],bitmapoffset[1],header.cupsWidth,header.cupsHeight); - newdata = (unsigned char *)malloc(sizeof(char)*3*im.width()*im.height()); - newdata = removeAlpha((unsigned char *)im.const_data(),newdata,im.width(),im.height()); - pixel_count=im.width()*im.height(); + // im = pr.render_page(current_page,header.HWResolution[0],header.HWResolution[1],bitmapoffset[0],bitmapoffset[1],header.cupsWidth,header.cupsHeight); + // newdata = (unsigned char *)malloc(sizeof(char)*3*im.width()*im.height()); + // newdata = removeAlpha((unsigned char *)im.const_data(),newdata,im.width(),im.height()); + // pixel_count=im.width()*im.height(); + FPDF_RenderPageBitmap(bitmap.get(), current_page, bitmapoffset[0], bitmapoffset[1], header.cupsWidth, header.cupsHeight, 0, 0); + void *buffer = FPDFBitmap_GetBuffer(bitmap.get()); + newdata = (unsigned char *)malloc(sizeof(char)*3*header.cupsWidth*header.cupsHeight); + newdata = removeAlpha((unsigned char *)buffer, newdata, header.cupsWidth, header.cupsHeight); + pixel_count=header.cupsWidth * header.cupsHeight; rowsize=header.cupsWidth*3; colordata=newdata; break; @@ -1649,7 +1659,7 @@ static void writePageImage(cups_raster_t *raster, poppler::document *doc, if (allocLineBuf) delete[] lineBuf; } -static void outPage(poppler::document *doc, int pageNo, +static void outPage(FPDF_DOCUMENT doc, int pageNo, cups_raster_t *raster) { int rotate = 0; @@ -1661,28 +1671,19 @@ static void outPage(poppler::document *doc, int pageNo, int imageable_area_fit = 0; int i; - poppler::page *current_page =doc->create_page(pageNo-1); - poppler::page_box_enum box = poppler::page_box_enum::media_box; - poppler::rectf mediaBox = current_page->page_rect(box); - poppler::page::orientation_enum orient = current_page->orientation(); - switch (orient) { - case poppler::page::landscape: rotate=90; - break; - case poppler::page::upside_down: rotate=180; - break; - case poppler::page::seascape: rotate=270; - break; - default:rotate=0; - } + FPDF_PAGE current_page = FPDF_LoadPage(doc, pageNo - 1); + FS_RECTF mediaBox; + FPDFPage_GetMediaBox(current_page, &mediaBox.left, &mediaBox.bottom, &mediaBox.right, &mediaBox.top); + rotate = FPDFPage_GetRotation(current_page); fprintf(stderr, "DEBUG: mediaBox = [ %f %f %f %f ]; rotate = %d\n", - mediaBox.left(), mediaBox.top(), mediaBox.right(), mediaBox.bottom(), rotate); - l = mediaBox.width(); + mediaBox.left, mediaBox.top, mediaBox.right, mediaBox.bottom, rotate); + l = mediaBox.right - mediaBox.left; if (l < 0) l = -l; if (rotate == 90 || rotate == 270) header.PageSize[1] = (unsigned)l; else header.PageSize[0] = (unsigned)l; - l = mediaBox.height(); + l = mediaBox.bottom - mediaBox.top; if (l < 0) l = -l; if (rotate == 90 || rotate == 270) header.PageSize[0] = (unsigned)l; @@ -1831,8 +1832,8 @@ static void outPage(poppler::document *doc, int pageNo, } if (imageable_area_fit == 0) { - bitmapoffset[0] = margins[0] / 72.0 * header.HWResolution[0]; - bitmapoffset[1] = margins[3] / 72.0 * header.HWResolution[1]; + bitmapoffset[0] = margins[0]; + bitmapoffset[1] = margins[3]; } else { bitmapoffset[0] = 0; bitmapoffset[1] = 0; @@ -1884,6 +1885,7 @@ static void outPage(poppler::document *doc, int pageNo, /* write page image */ writePageImage(raster,doc,pageNo); + FPDF_ClosePage(current_page); } static void setPopplerColorProfile() @@ -1972,11 +1974,12 @@ static void setPopplerColorProfile() } int main(int argc, char *argv[]) { - poppler::document *doc; + FPDF_DOCUMENT doc; int i; int npages=0; cups_raster_t *raster; + FPDF_InitLibrary(); cmsSetLogErrorHandler(lcmsErrorHandler); parseOpts(argc, argv); @@ -2002,7 +2005,7 @@ int main(int argc, char *argv[]) { } } close(fd); - doc=poppler::document::load_from_file(name,"",""); + doc = FPDF_LoadDocument(name, NULL); /* remove name */ unlink(name); } else { @@ -2015,14 +2018,21 @@ int main(int argc, char *argv[]) { } parsePDFTOPDFComment(fp); fclose(fp); - doc=poppler::document::load_from_file(argv[6],"",""); + doc = FPDF_LoadDocument(argv[6], NULL); } if(doc != NULL) - npages = doc->pages(); - + npages = FPDF_GetPageCount(doc); + fprintf(stderr, "ERROR: npages: %d\n", npages); /* fix NumCopies, Collate ccording to PDFTOPDFComments */ - header.NumCopies = deviceCopies; + if (cupsManualCopies) { + fprintf(stderr, "ERROR: Using cups to handle the number of printed copies\n"); + header.NumCopies = atoi(argv[4]); + } else { + fprintf(stderr, "ERROR: The printer handles the number of printed copies\n"); + header.NumCopies = 1; + } + fprintf(stderr, "ERROR: NumCopies: %d\n", header.NumCopies); header.Collate = deviceCollate ? CUPS_TRUE : CUPS_FALSE; /* fixed other values that pdftopdf handles */ header.MirrorPrint = CUPS_FALSE; @@ -2119,15 +2129,16 @@ int main(int argc, char *argv[]) { } selectConvertFunc(raster); if(doc != NULL){ - for (i = 1;i <= npages;i++) { - outPage(doc,i,raster); + for (int j = 0; j < header.NumCopies; j++) { + for (i = 1;i <= npages;i++) { + outPage(doc,i,raster); + } } } else fprintf(stderr, "DEBUG: Input is empty, outputting empty file.\n"); cupsRasterClose(raster); - delete doc; if (ppd != NULL) { ppdClose(ppd); } @@ -2140,33 +2151,9 @@ int main(int argc, char *argv[]) { if (colorTransform != NULL) { cmsDeleteTransform(colorTransform); } - + if (doc != nullptr) { + FPDF_CloseDocument(doc); + } + FPDF_DestroyLibrary(); return exitCode; } - -/* replace memory allocation methods for memory check */ -/* For compatibility with g++ >= 4.7 compilers _GLIBCXX_THROW - * should be used as a guard, otherwise use traditional definition */ -#ifndef _GLIBCXX_THROW -#define _GLIBCXX_THROW throw -#endif - -void * operator new(size_t size) _GLIBCXX_THROW (std::bad_alloc) -{ - return malloc(size); -} - -void operator delete(void *p) throw () -{ - free(p); -} - -void * operator new[](size_t size) _GLIBCXX_THROW (std::bad_alloc) -{ - return malloc(size); -} - -void operator delete[](void *p) throw () -{ - free(p); -}