src/psio1.c
l_int32
pixWriteSegmentedPageToPS(PIX         *pixs,
                          PIX         *pixm,
                          l_float32    textscale,
                          l_float32    imagescale,
                          l_int32      threshold,
                          l_int32      pageno,
                          const char  *fileout)
{
l_int32    alltext, notext, d, ret;
l_uint32   val;
l_float32  scaleratio;
PIX       *pixmi, *pixmis, *pixt, *pixg, *pixsc, *pixb, *pixc;

    PROCNAME("pixWriteSegmentedPageToPS");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if (imagescale <= 0.0 || textscale <= 0.0)
        return ERROR_INT("relative scales must be > 0.0", procName, 1);

        /* Analyze the page.  Determine the ratio by which the
         * binary text mask is scaled relative to the image part.
         * If there is no image region (alltext == TRUE), the
         * text mask will be rendered directly to fit the page,
         * and scaleratio = 1.0.  */
    alltext = TRUE;
    notext = FALSE;
    scaleratio = 1.0;
    if (pixm) {
        pixZero(pixm, &alltext);  /* pixm empty: all text */
        if (alltext)
            pixm = NULL;  /* treat it as not existing here */
        else {
            pixmi = pixInvert(NULL, pixm);
            pixZero(pixmi, &notext);  /* pixm full; no text */
            pixDestroy(&pixmi);
            scaleratio = textscale / imagescale;
        }
    }

    if (pixGetDepth(pixs) == 1) {  /* render tiff g4 */
        pixb = pixClone(pixs);
        pixc = NULL;
    }
    else {
        pixt = pixConvertTo8Or32(pixs, 0, 0);  /* this can be a clone of pixs */

            /* Get the binary text mask.  Note that pixg cannot be a
             * clone of pixs, because it may be altered by pixSetMasked(). */
        pixb = NULL;
        if (notext == FALSE) {
            d = pixGetDepth(pixt);
            if (d == 8)
                pixg = pixCopy(NULL, pixt);
            else  /* d == 32 */
                pixg = pixConvertRGBToLuminance(pixt);
            if (pixm)  /* clear out the image parts */
                pixSetMasked(pixg, pixm, 255);
            if (textscale == 1.0)
                pixsc = pixClone(pixg);
            else if (textscale >= 0.7)
                pixsc = pixScaleGrayLI(pixg, textscale, textscale);
            else
                pixsc = pixScaleAreaMap(pixg, textscale, textscale);
            pixb = pixThresholdToBinary(pixsc, threshold);
            pixDestroy(&pixg);
            pixDestroy(&pixsc);
        }

            /* Get the scaled image region */
        pixc = NULL;
        if (pixm) {
            if (imagescale == 1.0)
                pixsc = pixClone(pixt);  /* can possibly be a clone of pixs */
            else
                pixsc = pixScale(pixt, imagescale, imagescale);

                /* If pixm is not full, clear the pixels in pixsc
                 * corresponding to bg in pixm, where there can be text
                 * that is written through the mask pixb.  Note that
                 * we could skip this and use pixsc directly in
                 * pixWriteMixedToPS(); however, clearing these
                 * non-image regions to a white background will reduce
                 * the size of pixc (relative to pixsc), and hence
                 * reduce the size of the PS file that is generated.
                 * Use a copy so that we don't accidentally alter pixs.  */
            if (notext == FALSE) {
                pixmis = pixScale(pixm, imagescale, imagescale);
                pixmi = pixInvert(NULL, pixmis);
                val = (d == 8) ? 0xff : 0xffffff00;
                pixc = pixCopy(NULL, pixsc);
                pixSetMasked(pixc, pixmi, val);  /* clear non-image part */
                pixDestroy(&pixmis);
                pixDestroy(&pixmi);
            }
            else
                pixc = pixClone(pixsc);
            pixDestroy(&pixsc);
        }
        pixDestroy(&pixt);
    }

        /* Generate the PS file.  Don't use bounding boxes. */
    l_psWriteBoundingBox(FALSE);
    ret = pixWriteMixedToPS(pixb, pixc, scaleratio, pageno, fileout);
    l_psWriteBoundingBox(TRUE);
    pixDestroy(&pixb);
    pixDestroy(&pixc);
    return ret;
}
/*
 *  pixWriteSegmentedPageToPS()
 *
 *      Input:  pixs (all depths; colormap ok)
 *              pixm (<optional> 1 bpp segmentation mask over image region)
 *              textscale (scale of text output relative to pixs)
 *              imagescale (scale of image output relative to pixs)
 *              threshold (threshold for binarization; typ. 190)
 *              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 generates the PS string for a mixed text/image page,
 *          and adds it to an existing file if @pageno > 1.
 *          The PS output is determined by fitting the result to
 *          a letter-size (8.5 x 11 inch) page.
 *      (2) The two images (pixs and pixm) are at the same resolution
 *          (typically 300 ppi).  They are used to generate two compressed
 *          images, pixb and pixc, that are put directly into the output
 *          PS file.
 *      (3) pixb is the text component.  In the PostScript world, we think of
 *          it as a mask through which we paint black.  It is produced by
 *          scaling pixs by @textscale, and thresholding to 1 bpp.
 *      (4) pixc is the image component, which is that part of pixs under
 *          the mask pixm.  It is scaled from pixs by @imagescale.
 *      (5) Typical values are textscale = 2.0 and imagescale = 0.5.
 *      (6) If pixm == NULL, the page has only text.  If it is all black,
 *          the page is all image and has no text.
 *      (7) This can be used to write a multi-page PS file, by using
 *          sequential page numbers with the same output file.  It can
 *          also be used to write separate PS files for each page,
 *          by using different output files with @pageno = 0 or 1.
 */
pixWriteSegmentedPageToPS()
Input:  pixs (all depths; colormap ok)
pixm ( 1 bpp segmentation mask over image region)
textscale (scale of text output relative to pixs)
imagescale (scale of image output relative to pixs)
threshold (threshold for binarization; typ. 190)
pageno (page number in set; use 1 for new output file)
fileout (output ps file)
Return: 0 if OK, 1 on error

(1) This generates the PS string for a mixed text/image page,
and adds it to an existing file if @pageno > 1.
The PS output is determined by fitting the result to
a letter-size (8.5 x 11 inch) page.
(2) The two images (pixs and pixm) are at the same resolution
(typically 300 ppi).  They are used to generate two compressed
images, pixb and pixc, that are put directly into the output
PS file.
(3) pixb is the text component.  In the PostScript world, we think of
it as a mask through which we paint black.  It is produced by
scaling pixs by @textscale, and thresholding to 1 bpp.
(4) pixc is the image component, which is that part of pixs under
the mask pixm.  It is scaled from pixs by @imagescale.
(5) Typical values are textscale = 2.0 and imagescale = 0.5.
(6) If pixm == NULL, the page has only text.  If it is all black,
the page is all image and has no text.
(7) This can be used to write a multi-page PS file, by using
sequential page numbers with the same output file.  It can
also be used to write separate PS files for each page,
by using different output files with @pageno = 0 or 1.
pixWriteSegmentedPageToPS () Input : pixs ( all depths ; colormap ok ) pixm ( 1 bpp segmentation mask over image region ) textscale ( scale of text output relative to pixs ) imagescale ( scale of image output relative to pixs ) threshold ( threshold for binarization ; typ . 190 ) pageno ( page number in set ; use 1 for new output file ) fileout ( output ps file ) Return : 0 if OK 1 on error ( 1 ) This generates the PS string for a mixed text / image page and adds it to an existing file if @pageno > 1 . The PS output is determined by fitting the result to a letter - size ( 8 . 5 x 11 inch ) page . ( 2 ) The two images ( pixs and pixm ) are at the same resolution ( typically 300 ppi ) . They are used to generate two compressed images pixb and pixc that are put directly into the output PS file . ( 3 ) pixb is the text component . In the PostScript world we think of it as a mask through which we paint black . It is produced by scaling pixs by @textscale and thresholding to 1 bpp . ( 4 ) pixc is the image component which is that part of pixs under the mask pixm . It is scaled from pixs by @imagescale . ( 5 ) Typical values are textscale = 2 . 0 and imagescale = 0 . 5 . ( 6 ) If pixm == NULL the page has only text . If it is all black the page is all image and has no text . ( 7 ) This can be used to write a multi - page PS file by using sequential page numbers with the same output file . It can also be used to write separate PS files for each page by using different output files with @pageno = 0 or 1 .
l_int32
pixWriteSegmentedPageToPS(PIX         *pixs,
                          PIX         *pixm,
                          l_float32    textscale,
                          l_float32    imagescale,
                          l_int32      threshold,
                          l_int32      pageno,
                          const char  *fileout)
{
l_int32    alltext, notext, d, ret;
l_uint32   val;
l_float32  scaleratio;
PIX       *pixmi, *pixmis, *pixt, *pixg, *pixsc, *pixb, *pixc;
    PROCNAME("pixWriteSegmentedPageToPS");
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if (imagescale <= 0.0 || textscale <= 0.0)
        return ERROR_INT("relative scales must be > 0.0", procName, 1);
    alltext = TRUE;
    notext = FALSE;
    scaleratio = 1.0;
    if (pixm) {
        pixZero(pixm, &alltext);  
        if (alltext)
            pixm = NULL;  
        else {
            pixmi = pixInvert(NULL, pixm);
            pixZero(pixmi, &notext);  
            pixDestroy(&pixmi);
            scaleratio = textscale / imagescale;
        }
    }
    if (pixGetDepth(pixs) == 1) {  
        pixb = pixClone(pixs);
        pixc = NULL;
    }
    else {
        pixt = pixConvertTo8Or32(pixs, 0, 0);  
        pixb = NULL;
        if (notext == FALSE) {
            d = pixGetDepth(pixt);
            if (d == 8)
                pixg = pixCopy(NULL, pixt);
            else  
                pixg = pixConvertRGBToLuminance(pixt);
            if (pixm)  
                pixSetMasked(pixg, pixm, 255);
            if (textscale == 1.0)
                pixsc = pixClone(pixg);
            else if (textscale >= 0.7)
                pixsc = pixScaleGrayLI(pixg, textscale, textscale);
            else
                pixsc = pixScaleAreaMap(pixg, textscale, textscale);
            pixb = pixThresholdToBinary(pixsc, threshold);
            pixDestroy(&pixg);
            pixDestroy(&pixsc);
        }
        pixc = NULL;
        if (pixm) {
            if (imagescale == 1.0)
                pixsc = pixClone(pixt);  
            else
                pixsc = pixScale(pixt, imagescale, imagescale);
            if (notext == FALSE) {
                pixmis = pixScale(pixm, imagescale, imagescale);
                pixmi = pixInvert(NULL, pixmis);
                val = (d == 8) ? 0xff : 0xffffff00;
                pixc = pixCopy(NULL, pixsc);
                pixSetMasked(pixc, pixmi, val);  
                pixDestroy(&pixmis);
                pixDestroy(&pixmi);
            }
            else
                pixc = pixClone(pixsc);
            pixDestroy(&pixsc);
        }
        pixDestroy(&pixt);
    }
    l_psWriteBoundingBox(FALSE);
    ret = pixWriteMixedToPS(pixb, pixc, scaleratio, pageno, fileout);
    l_psWriteBoundingBox(TRUE);
    pixDestroy(&pixb);
    pixDestroy(&pixc);
    return ret;
}
l_int32 pixWriteSegmentedPageToPS ( PIX * pixs , PIX * pixm , l_float32 textscale , l_float32 imagescale , l_int32 threshold , l_int32 pageno , const char * fileout ) { l_int32 alltext , notext , d , ret ; l_uint32 val ; l_float32 scaleratio ; PIX * pixmi , * pixmis , * pixt , * pixg , * pixsc , * pixb , * pixc ; PROCNAME ( " " ) ; if ( ! pixs ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! fileout ) return ERROR_INT ( " " , procName , 1 ) ; if ( imagescale <= 0.0 || textscale <= 0.0 ) return ERROR_INT ( " " , procName , 1 ) ; alltext = TRUE ; notext = FALSE ; scaleratio = 1.0 ; if ( pixm ) { pixZero ( pixm , & alltext ) ; if ( alltext ) pixm = NULL ; else { pixmi = pixInvert ( NULL , pixm ) ; pixZero ( pixmi , & notext ) ; pixDestroy ( & pixmi ) ; scaleratio = textscale / imagescale ; } } if ( pixGetDepth ( pixs ) == 1 ) { pixb = pixClone ( pixs ) ; pixc = NULL ; } else { pixt = pixConvertTo8Or32 ( pixs , 0 , 0 ) ; pixb = NULL ; if ( notext == FALSE ) { d = pixGetDepth ( pixt ) ; if ( d == 8 ) pixg = pixCopy ( NULL , pixt ) ; else pixg = pixConvertRGBToLuminance ( pixt ) ; if ( pixm ) pixSetMasked ( pixg , pixm , 255 ) ; if ( textscale == 1.0 ) pixsc = pixClone ( pixg ) ; else if ( textscale >= 0.7 ) pixsc = pixScaleGrayLI ( pixg , textscale , textscale ) ; else pixsc = pixScaleAreaMap ( pixg , textscale , textscale ) ; pixb = pixThresholdToBinary ( pixsc , threshold ) ; pixDestroy ( & pixg ) ; pixDestroy ( & pixsc ) ; } pixc = NULL ; if ( pixm ) { if ( imagescale == 1.0 ) pixsc = pixClone ( pixt ) ; else pixsc = pixScale ( pixt , imagescale , imagescale ) ; if ( notext == FALSE ) { pixmis = pixScale ( pixm , imagescale , imagescale ) ; pixmi = pixInvert ( NULL , pixmis ) ; val = ( d == 8 ) ? 0xff : 0xffffff00 ; pixc = pixCopy ( NULL , pixsc ) ; pixSetMasked ( pixc , pixmi , val ) ; pixDestroy ( & pixmis ) ; pixDestroy ( & pixmi ) ; } else pixc = pixClone ( pixsc ) ; pixDestroy ( & pixsc ) ; } pixDestroy ( & pixt ) ; } l_psWriteBoundingBox ( FALSE ) ; ret = pixWriteMixedToPS ( pixb , pixc , scaleratio , pageno , fileout ) ; l_psWriteBoundingBox ( TRUE ) ; pixDestroy ( & pixb ) ; pixDestroy ( & pixc ) ; return ret ; }
pixWriteSegmentedPageToPS()
      Input:  pixs (all depths; colormap ok)
              pixm (<optional> 1 bpp segmentation mask over image region)
              textscale (scale of text output relative to pixs)
              imagescale (scale of image output relative to pixs)
              threshold (threshold for binarization; typ.
pixWriteSegmentedPageToPS () Input : pixs ( all depths ; colormap ok ) pixm ( <optional > 1 bpp segmentation mask over image region ) textscale ( scale of text output relative to pixs ) imagescale ( scale of image output relative to pixs ) threshold ( threshold for binarization ; typ .
/* Analyze the page.  Determine the ratio by which the
         * binary text mask is scaled relative to the image part.
         * If there is no image region (alltext == TRUE), the
         * text mask will be rendered directly to fit the page,
         * and scaleratio = 1.0.  */ /* pixm empty: all text */ /* treat it as not existing here */ /* pixm full; no text */ /* render tiff g4 */ /* this can be a clone of pixs */ /* Get the binary text mask.  Note that pixg cannot be a
             * clone of pixs, because it may be altered by pixSetMasked(). */ /* d == 32 */ /* clear out the image parts */ /* Get the scaled image region */ /* can possibly be a clone of pixs */ /* If pixm is not full, clear the pixels in pixsc
                 * corresponding to bg in pixm, where there can be text
                 * that is written through the mask pixb.  Note that
                 * we could skip this and use pixsc directly in
                 * pixWriteMixedToPS(); however, clearing these
                 * non-image regions to a white background will reduce
                 * the size of pixc (relative to pixsc), and hence
                 * reduce the size of the PS file that is generated.
                 * Use a copy so that we don't accidentally alter pixs.  */ /* clear non-image part */ /* Generate the PS file.  Don't use bounding boxes. */