/* * pixWriteMixedToPS() * * Input: pixb (<optionall> 1 bpp "mask"; typically for text) * pixc (<optional> 8 or 32 bpp image regions) * scale (relative scale factor for rendering pixb * relative to pixc; typ. 4.0) * pageno (page number in set; use 1 for new output file) * fileout (output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) This low level function generates the PS string for a mixed * text/image page, and adds it to an existing file if * %pageno > 1. * (2) The two images (pixb and pixc) are typically generated at the * resolution that they will be rendered in the PS file. * (3) pixb is the text component. In the PostScript world, we think of * it as a mask through which we paint black. * (4) pixc is the (typically halftone) image component. It is * white in the rest of the page. To minimize the size of the * PS file, it should be rendered at a resolution that is at * least equal to its actual resolution. * (5) %scale gives the ratio of resolution of pixb to pixc. * Typical resolutions are: 600 ppi for pixb, 150 ppi for pixc; * so %scale = 4.0. If one of the images is not defined, * the value of %scale is ignored. * (6) We write pixc with DCT compression (jpeg). This is followed * by painting the text as black through the mask pixb. If * pixc doesn't exist (alltext), we write the text with the * PS "image" operator instead of the "imagemask" operator, * because ghostscript's ps2pdf is flaky when the latter is used. * (7) The actual output resolution is determined by fitting the * result to a letter-size (8.5 x 11 inch) page. */ l_int32 pixWriteMixedToPS(PIX *pixb, PIX *pixc, l_float32 scale, l_int32 pageno, const char *fileout) { char *tname; const char *op; l_int32 resb, resc, endpage, maskop, ret; PROCNAME("pixWriteMixedToPS"); if (!pixb && !pixc) return ERROR_INT("pixb and pixc both undefined", procName, 1); if (!fileout) return ERROR_INT("fileout not defined", procName, 1); /* Compute the resolution that fills a letter-size page. */ if (!pixc) { resb = getResLetterPage(pixGetWidth(pixb), pixGetHeight(pixb), 0); } else { resc = getResLetterPage(pixGetWidth(pixc), pixGetHeight(pixc), 0); if (pixb) resb = (l_int32)(scale * resc); } /* Write the jpeg image first */ if (pixc) { tname = l_makeTempFilename(NULL); pixWrite(tname, pixc, IFF_JFIF_JPEG); endpage = (pixb) ? FALSE : TRUE; op = (pageno <= 1) ? "w" : "a"; ret = convertJpegToPS(tname, fileout, op, 0, 0, resc, 1.0, pageno, endpage); lept_rmfile(tname); LEPT_FREE(tname); if (ret) return ERROR_INT("jpeg data not written", procName, 1); } /* Write the binary data, either directly or, if there is * a jpeg image on the page, through the mask. */ if (pixb) { tname = l_makeTempFilename(NULL); pixWrite(tname, pixb, IFF_TIFF_G4); op = (pageno <= 1 && !pixc) ? "w" : "a"; maskop = (pixc) ? 1 : 0; ret = convertG4ToPS(tname, fileout, op, 0, 0, resb, 1.0, pageno, maskop, 1); lept_rmfile(tname); LEPT_FREE(tname); if (ret) return ERROR_INT("tiff data not written", procName, 1); } return 0; }
/* * writeImageCompressedToPSFile() * * Input: filein (input image file) * fileout (output ps file) * res (output printer resolution) * &firstfile (<input and return> 1 if the first image; * 0 otherwise) * &index (<input and return> index of image in output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) This wraps a single page image in PS. * (2) The input file can be in any format. It is compressed as follows: * * if in tiffg4 --> use ccittg4 * * if in jpeg --> use dct * * all others --> use flate * (3) @index is incremented if the page is successfully written. */ l_int32 writeImageCompressedToPSFile(const char *filein, const char *fileout, l_int32 res, l_int32 *pfirstfile, l_int32 *pindex) { const char *op; l_int32 format, retval; FILE *fp; PROCNAME("writeImageCompressedToPSFile"); if (!pfirstfile || !pindex) return ERROR_INT("&firstfile and &index not defined", procName, 1); if ((fp = fopenReadStream(filein)) == NULL) return ERROR_INT("filein not found", procName, 1); findFileFormat(fp, &format); fclose(fp); if (format == IFF_UNKNOWN) { L_ERROR_STRING("Format of %s not known", procName, filein); return 1; } op = (*pfirstfile == TRUE) ? "w" : "a"; if (format == IFF_JFIF_JPEG) { retval = convertJpegToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } else if (format == IFF_TIFF_G4) { retval = convertTiffG4ToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, FALSE, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } else { /* all other image formats */ retval = convertFlateToPS(filein, fileout, op, 0, 0, res, 1.0, *pindex + 1, TRUE); if (retval == 0) { *pfirstfile = FALSE; (*pindex)++; } } return retval; }
int main(int argc, char **argv) { char *filein, *fileout, *fname; char buffer[512]; const char *psfile = "/tmp/junk_split_image.ps"; l_int32 nx, ny, i, w, h, d, ws, hs, n, res, ignore; l_float32 scale; PIX *pixs, *pixt, *pixr; PIXA *pixa; static char mainName[] = "splitimage2pdf"; if (argc != 5) return ERROR_INT(" Syntax: splitimage2pdf filein nx ny fileout", mainName, 1); filein = argv[1]; nx = atoi(argv[2]); ny = atoi(argv[3]); fileout = argv[4]; lept_rm(NULL, "junk_split_image.ps"); if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("pixs not made", mainName, 1); d = pixGetDepth(pixs); if (d == 1 ) lept_rm(NULL, "junk_split_image.tif"); else if (d == 8 || d == 32) lept_rm(NULL, "junk_split_image.jpg"); else return ERROR_INT("d not in {1,8,32} bpp", mainName, 1); pixGetDimensions(pixs, &ws, &hs, NULL); if (ny * ws > nx * hs) pixr = pixRotate90(pixs, 1); else pixr = pixClone(pixs); pixa = pixaSplitPix(pixr, nx, ny, 0, 0); n = pixaGetCount(pixa); res = 300; for (i = 0; i < n; i++) { pixt = pixaGetPix(pixa, i, L_CLONE); pixGetDimensions(pixt, &w, &h, NULL); scale = L_MIN(FILL_FACTOR * 2550 / w, FILL_FACTOR * 3300 / h); fname = NULL; if (d == 1) { fname = genPathname("/tmp", "junk_split_image.tif"); pixWrite(fname, pixt, IFF_TIFF_G4); if (i == 0) { convertG4ToPS(fname, psfile, "w", 0, 0, 300, scale, 1, FALSE, TRUE); } else { convertG4ToPS(fname, psfile, "a", 0, 0, 300, scale, 1, FALSE, TRUE); } } else { fname = genPathname("/tmp", "junk_split_image.jpg"); pixWrite(fname, pixt, IFF_JFIF_JPEG); if (i == 0) { convertJpegToPS(fname, psfile, "w", 0, 0, 300, scale, 1, TRUE); } else { convertJpegToPS(fname, psfile, "a", 0, 0, 300, scale, 1, TRUE); } } lept_free(fname); pixDestroy(&pixt); } snprintf(buffer, sizeof(buffer), "ps2pdf %s %s", psfile, fileout); ignore = system(buffer); /* ps2pdf */ pixaDestroy(&pixa); pixDestroy(&pixr); pixDestroy(&pixs); return 0; }
main(int argc, char **argv) { l_int32 w, h, success, display; l_float32 factor, scale; BOX *box; FILE *fp, *fp1; PIX *pixs, *pixt; if (regTestSetup(argc, argv, &fp, &display, &success, NULL)) return 1; factor = 0.95; /* Uncompressed PS with scaling but centered on the page */ pixs = pixRead("feyn-fract.tif"); pixGetDimensions(pixs, &w, &h, NULL); scale = L_MIN(factor * 2550 / w, factor * 3300 / h); fp1 = fopen("/tmp/psio0.ps", "wb+"); pixWriteStreamPS(fp1, pixs, NULL, 300, scale); fclose(fp1); regTestCheckFile(fp, argv, "/tmp/psio0.ps", 0, &success); pixDestroy(&pixs); /* Uncompressed PS with scaling, with LL corner at (1500, 1500) mils */ pixs = pixRead("weasel4.11c.png"); pixGetDimensions(pixs, &w, &h, NULL); scale = L_MIN(factor * 2550 / w, factor * 3300 / h); box = boxCreate(1500, 1500, (l_int32)(1000 * scale * w / 300), (l_int32)(1000 * scale * h / 300)); fp1 = fopen("/tmp/psio1.ps", "wb+"); pixWriteStreamPS(fp1, pixs, box, 300, 1.0); fclose(fp1); regTestCheckFile(fp, argv, "/tmp/psio1.ps", 1, &success); boxDestroy(&box); pixDestroy(&pixs); /* DCT compressed PS with LL corner at (300, 1000) pixels */ pixs = pixRead("marge.jpg"); pixt = pixConvertTo32(pixs); pixWrite("/tmp/psio2.jpg", pixt, IFF_JFIF_JPEG); convertJpegToPS("/tmp/psio2.jpg", "/tmp/psio3.ps", "w", 300, 1000, 0, 4.0, 1, 1); regTestCheckFile(fp, argv, "/tmp/psio2.jpg", 2, &success); regTestCheckFile(fp, argv, "/tmp/psio3.ps", 3, &success); pixDestroy(&pixt); pixDestroy(&pixs); /* For each page, apply tiff g4 image first; then jpeg or png over it */ convertTiffG4ToPS("feyn.tif", "/tmp/psio4.ps", "w", 0, 0, 0, 1.0, 1, 1, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 500, 100, 300, 2.0, 1, 0); convertFlateToPS("weasel4.11c.png", "/tmp/psio4.ps", "a", 300, 400, 300, 6.0, 1, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 100, 800, 300, 1.5, 1, 1); convertTiffG4ToPS("feyn.tif", "/tmp/psio4.ps", "a", 0, 0, 0, 1.0, 2, 1, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 1000, 700, 300, 2.0, 2, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 100, 200, 300, 2.0, 2, 1); convertTiffG4ToPS("feyn.tif", "/tmp/psio4.ps", "a", 0, 0, 0, 1.0, 3, 1, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 200, 200, 300, 2.0, 3, 0); convertJpegToPS("marge.jpg", "/tmp/psio4.ps", "a", 200, 900, 300, 2.0, 3, 1); regTestCheckFile(fp, argv, "/tmp/psio4.ps", 4, &success); /* Now apply jpeg first; then paint through a g4 mask. * For gv, the first image with a b.b. determines the * window size for the canvas, so we put down the largest * image first. If we had rendered a small image first, * gv and evince will not show the entire page. However, after * conversion to pdf, everything works fine, regardless of the * order in which images are placed into the PS. That is * because the pdf interpreter is robust to bad hints, ignoring * the page hints and computing the bounding box from the * set of images rendered on the page. */ pixs = pixRead("wyom.jpg"); pixt = pixScaleToSize(pixs, 2528, 3300); pixWrite("/tmp/psio5.jpg", pixt, IFF_JFIF_JPEG); pixDestroy(&pixs); pixDestroy(&pixt); convertJpegToPS("/tmp/psio5.jpg", "/tmp/psio5.ps", "w", 0, 0, 0, 1.0, 1, 0); convertFlateToPS("weasel8.240c.png", "/tmp/psio5.ps", "a", 100, 100, 300, 5.0, 1, 0); convertFlateToPS("weasel8.149g.png", "/tmp/psio5.ps", "a", 200, 300, 300, 5.0, 1, 0); convertFlateToPS("weasel4.11c.png", "/tmp/psio5.ps", "a", 300, 500, 300, 5.0, 1, 0); convertTiffG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 1, 1, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 500, 100, 300, 2.0, 2, 0); convertFlateToPS("weasel4.11c.png", "/tmp/psio5.ps", "a", 300, 400, 300, 6.0, 2, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 100, 800, 300, 1.5, 2, 0); convertTiffG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 2, 1, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 500, 100, 300, 2.0, 3, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 100, 800, 300, 2.0, 3, 0); convertTiffG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 3, 1, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 1000, 700, 300, 2.0, 4, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 100, 200, 300, 2.0, 4, 0); convertTiffG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 4, 1, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 200, 200, 300, 2.0, 5, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 200, 900, 300, 2.0, 5, 0); convertTiffG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 5, 1, 1); regTestCheckFile(fp, argv, "/tmp/psio5.ps", 5, &success); /* Generation using segmentation masks */ convertSegmentedPagesToPS(".", "lion-page", ".", "lion-mask", 10, 0, 100, 2.0, 0.8, 190, "/tmp/psio6.ps"); regTestCheckFile(fp, argv, "/tmp/psio6.ps", 6, &success); regTestCleanup(argc, argv, fp, success, NULL); return 0; }
int main(int argc, char **argv) { l_int32 i, w, h; l_float32 factor, scale; BOX *box; FILE *fp1; PIX *pixs, *pixt; PIXA *pixa; SARRAY *sa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; factor = 0.95; /* Uncompressed PS with scaling but centered on the page */ pixs = pixRead("feyn-fract.tif"); pixGetDimensions(pixs, &w, &h, NULL); scale = L_MIN(factor * 2550 / w, factor * 3300 / h); fp1 = lept_fopen("/tmp/regout/psio0.ps", "wb+"); pixWriteStreamPS(fp1, pixs, NULL, 300, scale); lept_fclose(fp1); regTestCheckFile(rp, "/tmp/regout/psio0.ps"); /* 0 */ pixDestroy(&pixs); /* Uncompressed PS with scaling, with LL corner at (1500, 1500) mils */ pixs = pixRead("weasel4.11c.png"); pixGetDimensions(pixs, &w, &h, NULL); scale = L_MIN(factor * 2550 / w, factor * 3300 / h); box = boxCreate(1500, 1500, (l_int32)(1000 * scale * w / 300), (l_int32)(1000 * scale * h / 300)); fp1 = lept_fopen("/tmp/regout/psio1.ps", "wb+"); pixWriteStreamPS(fp1, pixs, box, 300, 1.0); lept_fclose(fp1); regTestCheckFile(rp, "/tmp/regout/psio1.ps"); /* 1 */ boxDestroy(&box); pixDestroy(&pixs); /* DCT compressed PS with LL corner at (300, 1000) pixels */ pixs = pixRead("marge.jpg"); pixt = pixConvertTo32(pixs); pixWrite("/tmp/regout/psio2.jpg", pixt, IFF_JFIF_JPEG); convertJpegToPS("/tmp/regout/psio2.jpg", "/tmp/regout/psio3.ps", "w", 300, 1000, 0, 4.0, 1, 1); regTestCheckFile(rp, "/tmp/regout/psio2.jpg"); /* 2 */ regTestCheckFile(rp, "/tmp/regout/psio3.ps"); /* 3 */ pixDestroy(&pixt); pixDestroy(&pixs); /* For each page, apply tiff g4 image first; then jpeg or png over it */ convertG4ToPS("feyn.tif", "/tmp/regout/psio4.ps", "w", 0, 0, 0, 1.0, 1, 1, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 500, 100, 300, 2.0, 1, 0); convertFlateToPS("weasel4.11c.png", "/tmp/regout/psio4.ps", "a", 300, 400, 300, 6.0, 1, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 100, 800, 300, 1.5, 1, 1); convertG4ToPS("feyn.tif", "/tmp/regout/psio4.ps", "a", 0, 0, 0, 1.0, 2, 1, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 1000, 700, 300, 2.0, 2, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 100, 200, 300, 2.0, 2, 1); convertG4ToPS("feyn.tif", "/tmp/regout/psio4.ps", "a", 0, 0, 0, 1.0, 3, 1, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 200, 200, 300, 2.0, 3, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio4.ps", "a", 200, 900, 300, 2.0, 3, 1); regTestCheckFile(rp, "/tmp/regout/psio4.ps"); /* 4 */ /* Now apply jpeg first; then paint through a g4 mask. * For gv, the first image with a b.b. determines the * window size for the canvas, so we put down the largest * image first. If we had rendered a small image first, * gv and evince will not show the entire page. However, after * conversion to pdf, everything works fine, regardless of the * order in which images are placed into the PS. That is * because the pdf interpreter is robust to bad hints, ignoring * the page hints and computing the bounding box from the * set of images rendered on the page. * * Concatenate several pages, with colormapped png, color * jpeg and tiffg4 images (with the g4 image acting as a mask * that we're painting black through. If the text layer * is painted first, the following images occlude it; otherwise, * the images remain in the background of the text. */ pixs = pixRead("wyom.jpg"); pixt = pixScaleToSize(pixs, 2528, 3300); pixWrite("/tmp/regout/psio5.jpg", pixt, IFF_JFIF_JPEG); pixDestroy(&pixs); pixDestroy(&pixt); convertJpegToPS("/tmp/regout/psio5.jpg", "/tmp/regout/psio5.ps", "w", 0, 0, 300, 1.0, 1, 0); convertFlateToPS("weasel8.240c.png", "/tmp/regout/psio5.ps", "a", 100, 100, 300, 5.0, 1, 0); convertFlateToPS("weasel8.149g.png", "/tmp/regout/psio5.ps", "a", 200, 300, 300, 5.0, 1, 0); convertFlateToPS("weasel4.11c.png", "/tmp/regout/psio5.ps", "a", 300, 500, 300, 5.0, 1, 0); convertG4ToPS("feyn.tif", "/tmp/regout/psio5.ps", "a", 0, 0, 0, 1.0, 1, 1, 1); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 500, 100, 300, 2.0, 2, 0); convertFlateToPS("weasel4.11c.png", "/tmp/regout/psio5.ps", "a", 300, 400, 300, 6.0, 2, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 100, 800, 300, 1.5, 2, 0); convertG4ToPS("feyn.tif", "/tmp/regout/psio5.ps", "a", 0, 0, 0, 1.0, 2, 1, 1); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 500, 100, 300, 2.0, 3, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 100, 800, 300, 2.0, 3, 0); convertG4ToPS("feyn.tif", "/tmp/regout/psio5.ps", "a", 0, 0, 0, 1.0, 3, 1, 1); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 700, 700, 300, 2.0, 4, 0); convertFlateToPS("weasel8.149g.png", "/tmp/regout/psio5.ps", "a", 400, 400, 300, 5.0, 4, 0); convertG4ToPS("feyn.tif", "/tmp/regout/psio5.ps", "a", 0, 0, 0, 1.0, 4, 1, 0); convertFlateToPS("weasel8.240c.png", "/tmp/regout/psio5.ps", "a", 100, 220, 300, 5.0, 4, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 100, 200, 300, 2.0, 4, 1); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 200, 200, 300, 1.5, 5, 0); convertFlateToPS("weasel8.240c.png", "/tmp/regout/psio5.ps", "a", 140, 80, 300, 7.0, 5, 0); convertG4ToPS("feyn.tif", "/tmp/regout/psio5.ps", "a", 0, 0, 0, 1.0, 5, 1, 0); convertFlateToPS("weasel8.149g.png", "/tmp/regout/psio5.ps", "a", 280, 310, 300, 5.0, 4, 0); convertJpegToPS("marge.jpg", "/tmp/regout/psio5.ps", "a", 200, 900, 300, 2.0, 5, 1); regTestCheckFile(rp, "/tmp/regout/psio5.ps"); /* 5 */ /* Generation using segmentation masks */ convertSegmentedPagesToPS(".", "lion-page", 10, ".", "lion-mask", 10, 0, 100, 2.0, 0.8, 190, "/tmp/regout/psio6.ps"); regTestCheckFile(rp, "/tmp/regout/psio6.ps"); /* 6 */ /* PS generation for embeddding */ convertJpegToPSEmbed("tetons.jpg", "/tmp/regout/psio7.ps"); regTestCheckFile(rp, "/tmp/regout/psio7.ps"); /* 7 */ convertG4ToPSEmbed("feyn-fract.tif", "/tmp/regout/psio8.ps"); regTestCheckFile(rp, "/tmp/regout/psio8.ps"); /* 8 */ convertFlateToPSEmbed("weasel8.240c.png", "/tmp/regout/psio9.ps"); regTestCheckFile(rp, "/tmp/regout/psio9.ps"); /* 9 */ /* Writing compressed from a pixa */ sa = sarrayCreate(0); for (i = 0; i < 11; i++) sarrayAddString(sa, WeaselNames[i], L_COPY); pixa = pixaReadFilesSA(sa); pixaWriteCompressedToPS(pixa, "/tmp/regout/psio10.ps", 0, 3); regTestCheckFile(rp, "/tmp/regout/psio10.ps"); /* 10 */ pixaDestroy(&pixa); sarrayDestroy(&sa); return regTestCleanup(rp); }