src/pdfio.c
l_int32
convertSegmentedFilesToPdf(const char  *dirname,
                           const char  *substr,
                           l_int32      res,
                           l_int32      type,
                           l_int32      thresh,
                           BOXAA       *baa,
                           l_int32      quality,
                           l_float32    scalefactor,
                           const char  *title,
                           const char  *fileout)
{
char     *fname;
l_uint8  *imdata, *data;
l_int32   i, npages, nboxa, nboxes, ret;
size_t    imbytes, databytes;
BOXA     *boxa;
L_BYTEA  *ba;
L_PTRA   *pa_data;
SARRAY   *sa;

    PROCNAME("convertSegmentedFilesToPdf");

    if (!dirname)
        return ERROR_INT("dirname not defined", procName, 1);
    if (!baa)
        return ERROR_INT("baa not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);

    if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
        return ERROR_INT("sa not made", procName, 1);

        /* Generate and save all the encoded pdf strings */
    npages = sarrayGetCount(sa);
    nboxa = boxaaGetCount(baa);
    if (npages != nboxa) {
        sarrayDestroy(&sa);
        return ERROR_INT("npages != nboxa", procName, 1);
    }
    pa_data = ptraCreate(npages);
    for (i = 0; i < npages; i++) {
        fname = sarrayGetString(sa, i, L_NOCOPY);
        boxa = boxaaGetBoxa(baa, i, L_CLONE);
        nboxes = boxaGetCount(boxa);
        if (nboxes == 0)
            boxaDestroy(&boxa);
        ret = convertToPdfDataSegmented(fname, res, type, thresh, boxa,
                                        quality, scalefactor,
                                        &imdata, &imbytes);
        boxaDestroy(&boxa);  /* safe; in case nboxes > 0 */
        if (ret) {
            L_ERROR_STRING("pdf encoding failed for %s", procName, fname);
            continue;
        }
        ba = l_byteaInitFromMem(imdata, imbytes);
        if (imdata) FREE(imdata);
        ptraAdd(pa_data, ba);
    }
    sarrayDestroy(&sa);

    ptraGetActualCount(pa_data, &npages);
    if (npages == 0) {
        L_ERROR("no pdf files made", procName);
        ptraDestroy(&pa_data, FALSE, FALSE);
        return 1;
    }

        /* Concatenate */
    ret = ptraConcatenatePdfToData(pa_data, NULL, &data, &databytes);

        /* Clean up */
    ptraGetActualCount(pa_data, &npages);  /* recalculate in case it changes */
    for (i = 0; i < npages; i++) {
        ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
        l_byteaDestroy(&ba);
    }
    ptraDestroy(&pa_data, FALSE, FALSE);

    if (ret) {
        if (data) FREE(data);
        return ERROR_INT("pdf data not made", procName, 1);
    }

    ret = l_binaryWrite(fileout, "w", data, databytes);
    FREE(data);
    if (ret)
        L_ERROR("pdf data not written to file", procName);
    return ret;
}
/*!
 *  convertSegmentedFilesToPdf()
 *
 *      Input:  directory name (containing images)
 *              substr (<optional> substring filter on filenames; can be NULL)
 *              res (input resolution of all images)
 *              type (compression type for non-image regions; the
 *                    image regions are always compressed with L_JPEG_ENCODE)
 *              thresh (used for converting gray --> 1 bpp with L_G4_ENCODE)
 *              boxaa (of image regions)
 *              quality (used for JPEG only; 0 for default (75))
 *              scalefactor (scaling factor applied to each image region)
 *              title (<optional> pdf title; if null, taken from the first
 *                     image filename)
 *              fileout (pdf file of all images)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) If @substr is not NULL, only image filenames that contain
 *          the substring can be used.  If @substr == NULL, all files
 *          in the directory are used.
 *      (2) The files in the directory, after optional filtering by
 *          the substring, are lexically sorted in increasing order
 *          before concatenation.
 *      (3) The images are encoded with G4 if 1 bpp; JPEG if 8 bpp without
 *          colormap and many colors, or 32 bpp; FLATE for anything else.
 *      (4) The boxaa contains one boxa of "image regions" for each
 *          image file.  The boxa must all exist, but they can be empty.
 *          They must be aligned with the sorted set of images.
 *      (5) The scalefactor is applied to each image region.  It is
 *          typically < 1.0, to save bytes in the final pdf, because
 *          the resolution is often not critical in non-text regions.
 *      (6) The non-image regions are automatically scaled up by 2x and
 *          thresholded if the encoding type is G4.  If the non-image
 *          regions are not encoded with G4, no scaling is performed on them.
 */


(1) If @substr is not NULL, only image filenames that contain
the substring can be used.  If @substr == NULL, all files
in the directory are used.
(2) The files in the directory, after optional filtering by
the substring, are lexically sorted in increasing order
before concatenation.
(3) The images are encoded with G4 if 1 bpp; JPEG if 8 bpp without
colormap and many colors, or 32 bpp; FLATE for anything else.
(4) The boxaa contains one boxa of "image regions" for each
image file.  The boxa must all exist, but they can be empty.
They must be aligned with the sorted set of images.
(5) The scalefactor is applied to each image region.  It is
typically < 1.0, to save bytes in the final pdf, because
the resolution is often not critical in non-text regions.
(6) The non-image regions are automatically scaled up by 2x and
thresholded if the encoding type is G4.  If the non-image
regions are not encoded with G4, no scaling is performed on them.
( 1 ) If @substr is not NULL only image filenames that contain the substring can be used . If @substr == NULL all files in the directory are used . ( 2 ) The files in the directory after optional filtering by the substring are lexically sorted in increasing order before concatenation . ( 3 ) The images are encoded with G4 if 1 bpp ; JPEG if 8 bpp without colormap and many colors or 32 bpp ; FLATE for anything else . ( 4 ) The boxaa contains one boxa of " image regions " for each image file . The boxa must all exist but they can be empty . They must be aligned with the sorted set of images . ( 5 ) The scalefactor is applied to each image region . It is typically < 1 . 0 to save bytes in the final pdf because the resolution is often not critical in non - text regions . ( 6 ) The non - image regions are automatically scaled up by 2x and thresholded if the encoding type is G4 . If the non - image regions are not encoded with G4 no scaling is performed on them .
l_int32
convertSegmentedFilesToPdf(const char  *dirname,
                           const char  *substr,
                           l_int32      res,
                           l_int32      type,
                           l_int32      thresh,
                           BOXAA       *baa,
                           l_int32      quality,
                           l_float32    scalefactor,
                           const char  *title,
                           const char  *fileout)
{
char     *fname;
l_uint8  *imdata, *data;
l_int32   i, npages, nboxa, nboxes, ret;
size_t    imbytes, databytes;
BOXA     *boxa;
L_BYTEA  *ba;
L_PTRA   *pa_data;
SARRAY   *sa;
    PROCNAME("convertSegmentedFilesToPdf");
    if (!dirname)
        return ERROR_INT("dirname not defined", procName, 1);
    if (!baa)
        return ERROR_INT("baa not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
        return ERROR_INT("sa not made", procName, 1);
    npages = sarrayGetCount(sa);
    nboxa = boxaaGetCount(baa);
    if (npages != nboxa) {
        sarrayDestroy(&sa);
        return ERROR_INT("npages != nboxa", procName, 1);
    }
    pa_data = ptraCreate(npages);
    for (i = 0; i < npages; i++) {
        fname = sarrayGetString(sa, i, L_NOCOPY);
        boxa = boxaaGetBoxa(baa, i, L_CLONE);
        nboxes = boxaGetCount(boxa);
        if (nboxes == 0)
            boxaDestroy(&boxa);
        ret = convertToPdfDataSegmented(fname, res, type, thresh, boxa,
                                        quality, scalefactor,
                                        &imdata, &imbytes);
        boxaDestroy(&boxa);  
        if (ret) {
            L_ERROR_STRING("pdf encoding failed for %s", procName, fname);
            continue;
        }
        ba = l_byteaInitFromMem(imdata, imbytes);
        if (imdata) FREE(imdata);
        ptraAdd(pa_data, ba);
    }
    sarrayDestroy(&sa);
    ptraGetActualCount(pa_data, &npages);
    if (npages == 0) {
        L_ERROR("no pdf files made", procName);
        ptraDestroy(&pa_data, FALSE, FALSE);
        return 1;
    }
    ret = ptraConcatenatePdfToData(pa_data, NULL, &data, &databytes);
    ptraGetActualCount(pa_data, &npages);  
    for (i = 0; i < npages; i++) {
        ba = (L_BYTEA *)ptraRemove(pa_data, i, L_NO_COMPACTION);
        l_byteaDestroy(&ba);
    }
    ptraDestroy(&pa_data, FALSE, FALSE);
    if (ret) {
        if (data) FREE(data);
        return ERROR_INT("pdf data not made", procName, 1);
    }
    ret = l_binaryWrite(fileout, "w", data, databytes);
    FREE(data);
    if (ret)
        L_ERROR("pdf data not written to file", procName);
    return ret;
}
l_int32 convertSegmentedFilesToPdf ( const char * dirname , const char * substr , l_int32 res , l_int32 type , l_int32 thresh , BOXAA * baa , l_int32 quality , l_float32 scalefactor , const char * title , const char * fileout ) { char * fname ; l_uint8 * imdata , * data ; l_int32 i , npages , nboxa , nboxes , ret ; size_t imbytes , databytes ; BOXA * boxa ; L_BYTEA * ba ; L_PTRA * pa_data ; SARRAY * sa ; PROCNAME ( " " ) ; if ( ! dirname ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! baa ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! fileout ) return ERROR_INT ( " " , procName , 1 ) ; if ( ( sa = getSortedPathnamesInDirectory ( dirname , substr , 0 , 0 ) ) == NULL ) return ERROR_INT ( " " , procName , 1 ) ; npages = sarrayGetCount ( sa ) ; nboxa = boxaaGetCount ( baa ) ; if ( npages != nboxa ) { sarrayDestroy ( & sa ) ; return ERROR_INT ( " " , procName , 1 ) ; } pa_data = ptraCreate ( npages ) ; for ( i = 0 ; i < npages ; i ++ ) { fname = sarrayGetString ( sa , i , L_NOCOPY ) ; boxa = boxaaGetBoxa ( baa , i , L_CLONE ) ; nboxes = boxaGetCount ( boxa ) ; if ( nboxes == 0 ) boxaDestroy ( & boxa ) ; ret = convertToPdfDataSegmented ( fname , res , type , thresh , boxa , quality , scalefactor , & imdata , & imbytes ) ; boxaDestroy ( & boxa ) ; if ( ret ) { L_ERROR_STRING ( " " , procName , fname ) ; continue ; } ba = l_byteaInitFromMem ( imdata , imbytes ) ; if ( imdata ) FREE ( imdata ) ; ptraAdd ( pa_data , ba ) ; } sarrayDestroy ( & sa ) ; ptraGetActualCount ( pa_data , & npages ) ; if ( npages == 0 ) { L_ERROR ( " " , procName ) ; ptraDestroy ( & pa_data , FALSE , FALSE ) ; return 1 ; } ret = ptraConcatenatePdfToData ( pa_data , NULL , & data , & databytes ) ; ptraGetActualCount ( pa_data , & npages ) ; for ( i = 0 ; i < npages ; i ++ ) { ba = ( L_BYTEA * ) ptraRemove ( pa_data , i , L_NO_COMPACTION ) ; l_byteaDestroy ( & ba ) ; } ptraDestroy ( & pa_data , FALSE , FALSE ) ; if ( ret ) { if ( data ) FREE ( data ) ; return ERROR_INT ( " " , procName , 1 ) ; } ret = l_binaryWrite ( fileout , " " , data , databytes ) ; FREE ( data ) ; if ( ret ) L_ERROR ( " " , procName ) ; return ret ; }
convertSegmentedFilesToPdf()
      Input:  directory name (containing images)
              substr (<optional> substring filter on filenames; can be NULL)
              res (input resolution of all images)
              type (compression type for non-image regions; the
                    image regions are always compressed with L_JPEG_ENCODE)
              thresh (used for converting gray --> 1 bpp with L_G4_ENCODE)
              boxaa (of image regions)
              quality (used for JPEG only; 0 for default (75))
              scalefactor (scaling factor applied to each image region)
              title (<optional> pdf title; if null, taken from the first
                     image filename)
              fileout (pdf file of all images)
      Return: 0 if OK, 1 on error
convertSegmentedFilesToPdf () Input : directory name ( containing images ) substr ( <optional > substring filter on filenames ; can be NULL ) res ( input resolution of all images ) type ( compression type for non - image regions ; the image regions are always compressed with L_JPEG_ENCODE ) thresh ( used for converting gray -- > 1 bpp with L_G4_ENCODE ) boxaa ( of image regions ) quality ( used for JPEG only ; 0 for default ( 75 )) scalefactor ( scaling factor applied to each image region ) title ( <optional > pdf title ; if null taken from the first image filename ) fileout ( pdf file of all images ) Return : 0 if OK 1 on error
/* Generate and save all the encoded pdf strings */ /* safe; in case nboxes > 0 */ /* Concatenate */ /* Clean up */ /* recalculate in case it changes */