/* * convertToPSEmbed() * * Input: filein (input image file -- any format) * fileout (output ps file) * level (compression: 1 (uncompressed), 2 or 3) * Return: 0 if OK, 1 on error * * Notes: * (1) This is a wrapper function that generates a PS file with * a bounding box, from any input image file. * (2) Do the best job of compression given the specified level. * %level=3 does flate compression on anything that is not * tiffg4 (1 bpp) or jpeg (8 bpp or rgb). * (3) If %level=2 and the file is not tiffg4 or jpeg, it will * first be written to file as jpeg with quality = 75. * This will remove the colormap and cause some degradation * in the image. * (4) The bounding box is required when a program such as TeX * (through epsf) places and rescales the image. It is * sized for fitting the image to an 8.5 x 11.0 inch page. */ l_int32 convertToPSEmbed(const char *filein, const char *fileout, l_int32 level) { const char nametif[] = "/tmp/junk_convert_ps_embed.tif"; const char namejpg[] = "/tmp/junk_convert_ps_embed.jpg"; l_int32 d, format; PIX *pix, *pixs; PROCNAME("convertToPSEmbed"); if (!filein) return ERROR_INT("filein not defined", procName, 1); if (!fileout) return ERROR_INT("fileout not defined", procName, 1); if (level != 1 && level != 2 && level != 3) { L_ERROR("invalid level specified; using level 2\n", procName); level = 2; } if (level == 1) { /* no compression */ pixWritePSEmbed(filein, fileout); return 0; } /* Find the format and write out directly if in jpeg or tiff g4 */ findFileFormat(filein, &format); if (format == IFF_JFIF_JPEG) { convertJpegToPSEmbed(filein, fileout); return 0; } else if (format == IFF_TIFF_G4) { convertG4ToPSEmbed(filein, fileout); return 0; } else if (format == IFF_UNKNOWN) { L_ERROR("format of %s not known\n", procName, filein); return 1; } /* If level 3, flate encode. */ if (level == 3) { convertFlateToPSEmbed(filein, fileout); return 0; } /* OK, it's level 2, so we must convert to jpeg or tiff g4 */ if ((pixs = pixRead(filein)) == NULL) return ERROR_INT("image not read from file", procName, 1); d = pixGetDepth(pixs); if ((d == 2 || d == 4) && !pixGetColormap(pixs)) pix = pixConvertTo8(pixs, 0); else if (d == 16) pix = pixConvert16To8(pixs, 1); else pix = pixRemoveColormap(pixs, REMOVE_CMAP_BASED_ON_SRC); d = pixGetDepth(pix); if (d == 1) { pixWrite(nametif, pix, IFF_TIFF_G4); convertG4ToPSEmbed(nametif, fileout); } else { pixWrite(namejpg, pix, IFF_JFIF_JPEG); convertJpegToPSEmbed(namejpg, fileout); } pixDestroy(&pix); pixDestroy(&pixs); return 0; }
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/psio0.ps", "wb+"); pixWriteStreamPS(fp1, pixs, NULL, 300, scale); lept_fclose(fp1); regTestCheckFile(rp, "/tmp/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/psio1.ps", "wb+"); pixWriteStreamPS(fp1, pixs, box, 300, 1.0); lept_fclose(fp1); regTestCheckFile(rp, "/tmp/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/psio2.jpg", pixt, IFF_JFIF_JPEG); convertJpegToPS("/tmp/psio2.jpg", "/tmp/psio3.ps", "w", 300, 1000, 0, 4.0, 1, 1); regTestCheckFile(rp, "/tmp/psio2.jpg"); /* 2 */ regTestCheckFile(rp, "/tmp/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/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); convertG4ToPS("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); convertG4ToPS("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(rp, "/tmp/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/psio5.jpg", pixt, IFF_JFIF_JPEG); pixDestroy(&pixs); pixDestroy(&pixt); convertJpegToPS("/tmp/psio5.jpg", "/tmp/psio5.ps", "w", 0, 0, 300, 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); convertG4ToPS("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); convertG4ToPS("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); convertG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 3, 1, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 700, 700, 300, 2.0, 4, 0); convertFlateToPS("weasel8.149g.png", "/tmp/psio5.ps", "a", 400, 400, 300, 5.0, 4, 0); convertG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 4, 1, 0); convertFlateToPS("weasel8.240c.png", "/tmp/psio5.ps", "a", 100, 220, 300, 5.0, 4, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 100, 200, 300, 2.0, 4, 1); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 200, 200, 300, 1.5, 5, 0); convertFlateToPS("weasel8.240c.png", "/tmp/psio5.ps", "a", 140, 80, 300, 7.0, 5, 0); convertG4ToPS("feyn.tif", "/tmp/psio5.ps", "a", 0, 0, 0, 1.0, 5, 1, 0); convertFlateToPS("weasel8.149g.png", "/tmp/psio5.ps", "a", 280, 310, 300, 5.0, 4, 0); convertJpegToPS("marge.jpg", "/tmp/psio5.ps", "a", 200, 900, 300, 2.0, 5, 1); regTestCheckFile(rp, "/tmp/psio5.ps"); /* 5 */ /* Generation using segmentation masks */ convertSegmentedPagesToPS(".", "lion-page", ".", "lion-mask", 10, 0, 100, 2.0, 0.8, 190, "/tmp/psio6.ps"); regTestCheckFile(rp, "/tmp/psio6.ps"); /* 6 */ /* PS generation for embeddding */ convertJpegToPSEmbed("tetons.jpg", "/tmp/psio7.ps"); regTestCheckFile(rp, "/tmp/psio7.ps"); /* 7 */ convertG4ToPSEmbed("feyn-fract.tif", "/tmp/psio8.ps"); regTestCheckFile(rp, "/tmp/psio8.ps"); /* 8 */ convertFlateToPSEmbed("weasel8.240c.png", "/tmp/psio9.ps"); regTestCheckFile(rp, "/tmp/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/psio10.ps", 0, 3); regTestCheckFile(rp, "/tmp/psio10.ps"); /* 10 */ pixaDestroy(&pixa); sarrayDestroy(&sa); return regTestCleanup(rp); }