/*! * lqueueDestroy() * * Input: &lqueue (<to be nulled>) * freeflag (TRUE to free each remaining struct in the array) * Return: void * * Notes: * (1) If freeflag is TRUE, frees each struct in the array. * (2) If freeflag is FALSE but there are elements on the array, * gives a warning and destroys the array. This will * cause a memory leak of all the items that were on the queue. * So if the items require their own destroy function, they * must be destroyed before the queue. The same applies to the * auxiliary stack, if it is used. * (3) To destroy the L_Queue, we destroy the ptr array, then * the lqueue, and then null the contents of the input ptr. */ void lqueueDestroy(L_QUEUE **plq, l_int32 freeflag) { void *item; L_QUEUE *lq; PROCNAME("lqueueDestroy"); if (plq == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((lq = *plq) == NULL) return; if (freeflag) { while(lq->nelem > 0) { item = lqueueRemove(lq); FREE(item); } } else if (lq->nelem > 0) { L_WARNING("memory leak of %d items in lqueue!\n", procName, lq->nelem); } if (lq->array) FREE(lq->array); if (lq->stack) lstackDestroy(&lq->stack, freeflag); FREE(lq); *plq = NULL; return; }
/*! * lheapDestroy() * * Input: &lheap (<to be nulled>) * freeflag (TRUE to free each remaining struct in the array) * Return: void * * Notes: * (1) Use freeflag == TRUE when the items in the array can be * simply destroyed using free. If those items require their * own destroy function, they must be destroyed before * calling this function, and then this function is called * with freeflag == FALSE. * (2) To destroy the lheap, we destroy the ptr array, then * the lheap, and then null the contents of the input ptr. */ void lheapDestroy(L_HEAP **plh, l_int32 freeflag) { l_int32 i; L_HEAP *lh; PROCNAME("lheapDestroy"); if (plh == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((lh = *plh) == NULL) return; if (freeflag) { /* free each struct in the array */ for (i = 0; i < lh->n; i++) FREE(lh->array[i]); } else if (lh->n > 0) { /* freeflag == FALSE but elements exist on array */ L_WARNING("memory leak of %d items in lheap!\n", procName, lh->n); } if (lh->array) FREE(lh->array); FREE(lh); *plh = NULL; return; }
/*! * ptraDestroy() * * Input: &ptra (<to be nulled>) * freeflag (TRUE to free each remaining item in the array) * warnflag (TRUE to warn if any remaining items are not destroyed) * Return: void * * Notes: * (1) If @freeflag == TRUE, frees each item in the array. * (2) If @freeflag == FALSE and warnflag == TRUE, and there are * items on the array, this gives a warning and destroys the array. * If these items are not owned elsewhere, this will cause * a memory leak of all the items that were on the array. * So if the items are not owned elsewhere and require their * own destroy function, they must be destroyed before the ptra. * (3) If warnflag == FALSE, no warnings will be issued. This is * useful if the items are owned elsewhere, such as a * PixMemoryStore(). * (4) To destroy the ptra, we destroy the ptr array, then * the ptra, and then null the contents of the input ptr. */ void ptraDestroy(L_PTRA **ppa, l_int32 freeflag, l_int32 warnflag) { l_int32 i, nactual; void *item; L_PTRA *pa; PROCNAME("ptraDestroy"); if (ppa == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((pa = *ppa) == NULL) return; ptraGetActualCount(pa, &nactual); if (nactual > 0) { if (freeflag) { for (i = 0; i <= pa->imax; i++) { if ((item = ptraRemove(pa, i, L_NO_COMPACTION)) != NULL) FREE(item); } } else if (warnflag) { L_WARNING("potential memory leak of %d items in ptra\n", procName, nactual); } } FREE(pa->array); FREE(pa); *ppa = NULL; return; }
/*! * bbufferDestroyAndSaveData() * * Input: &bbuffer (<to be nulled>) * &nbytes (<return> number of bytes saved in array) * Return: barray (newly allocated array of data) * * Notes: * (1) Copies data to newly allocated array; then destroys the bbuffer. */ l_uint8 * bbufferDestroyAndSaveData(BBUFFER **pbb, size_t *pnbytes) { l_uint8 *array; size_t nbytes; BBUFFER *bb; PROCNAME("bbufferDestroyAndSaveData"); if (pbb == NULL) { L_WARNING("ptr address is NULL\n", procName); return NULL; } if (pnbytes == NULL) { L_WARNING("&nbytes is NULL\n", procName); bbufferDestroy(pbb); return NULL; } if ((bb = *pbb) == NULL) return NULL; /* write all unwritten bytes out to a new array */ nbytes = bb->n - bb->nwritten; *pnbytes = nbytes; if ((array = (l_uint8 *)CALLOC(nbytes, sizeof(l_uint8))) == NULL) { L_WARNING("calloc failure for array\n", procName); return NULL; } memcpy((void *)array, (void *)(bb->array + bb->nwritten), nbytes); bbufferDestroy(pbb); return array; }
/*! * pixProjectivePtaGammaXform() * * Input: pixs (32 bpp rgb) * gamma (gamma correction; must be > 0.0) * ptad (3 pts of final coordinate space) * ptas (3 pts of initial coordinate space) * fract (between 0.0 and 1.0, with 1.0 fully transparent) * border (of pixels to capture transformed source pixels) * Return: pixd, or null on error * * Notes: * (1) This wraps a gamma/inverse-gamma photometric transform around * pixProjectivePtaWithAlpha(). * (2) For usage, see notes in pixProjectivePtaWithAlpha() and * pixGammaTRCWithAlpha(). * (3) The basic idea of a gamma/inverse-gamma transform is to remove * any gamma correction before the projective transform, and restore * it afterward. The effects can be subtle, but important for * some applications. For example, using gamma > 1.0 will * cause the dark areas to become somewhat lighter and slightly * reduce aliasing effects when blending using the alpha channel. */ PIX * pixProjectivePtaGammaXform(PIX *pixs, l_float32 gamma, PTA *ptad, PTA *ptas, l_float32 fract, l_int32 border) { PIX *pixg, *pixd; PROCNAME("pixProjectivePtaGammaXform"); if (!pixs || (pixGetDepth(pixs) != 32)) return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL); if (fract == 0.0) L_WARNING("fully opaque alpha; image cannot be blended", procName); if (gamma <= 0.0) { L_WARNING("gamma must be > 0.0; setting to 1.0", procName); gamma = 1.0; } pixg = pixGammaTRCWithAlpha(NULL, pixs, 1.0 / gamma, 0, 255); pixd = pixProjectivePtaWithAlpha(pixg, ptad, ptas, NULL, fract, border); pixGammaTRCWithAlpha(pixd, pixd, gamma, 0, 255); pixDestroy(&pixg); return pixd; }
/*! * lstackDestroy() * * Input: &lstack (<to be nulled>) * freeflag (TRUE to free each remaining struct in the array) * Return: void * * Notes: * (1) If freeflag is TRUE, frees each struct in the array. * (2) If freeflag is FALSE but there are elements on the array, * gives a warning and destroys the array. This will * cause a memory leak of all the items that were on the lstack. * So if the items require their own destroy function, they * must be destroyed before the lstack. * (3) To destroy the lstack, we destroy the ptr array, then * the lstack, and then null the contents of the input ptr. */ void lstackDestroy(L_STACK **plstack, l_int32 freeflag) { void *item; L_STACK *lstack; PROCNAME("lstackDestroy"); if (plstack == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((lstack = *plstack) == NULL) return; if (freeflag) { while(lstack->n > 0) { item = lstackRemove(lstack); LEPT_FREE(item); } } else if (lstack->n > 0) { L_WARNING("memory leak of %d items in lstack\n", procName, lstack->n); } if (lstack->auxstack) lstackDestroy(&lstack->auxstack, freeflag); if (lstack->array) LEPT_FREE(lstack->array); LEPT_FREE(lstack); *plstack = NULL; }
/*! * pixaDisplay() * * Input: pixa * w, h (if set to 0, determines the size from the * b.b. of the components in pixa) * Return: pix, or null on error * * Notes: * (1) This uses the boxes to place each pix in the rendered composite. * (2) Set w = h = 0 to use the b.b. of the components to determine * the size of the returned pix. * (3) Uses the first pix in pixa to determine the depth. * (4) The background is written "white". On 1 bpp, each successive * pix is "painted" (adding foreground), whereas for grayscale * or color each successive pix is blitted with just the src. * (5) If the pixa is empty, returns an empty 1 bpp pix. */ PIX * pixaDisplay(PIXA *pixa, l_int32 w, l_int32 h) { l_int32 i, n, d, xb, yb, wb, hb; BOXA *boxa; PIX *pixt, *pixd; PROCNAME("pixaDisplay"); if (!pixa) return (PIX *)ERROR_PTR("pixa not defined", procName, NULL); n = pixaGetCount(pixa); if (n == 0 && w == 0 && h == 0) return (PIX *)ERROR_PTR("no components; no size", procName, NULL); if (n == 0) { L_WARNING("no components; returning empty 1 bpp pix", procName); return pixCreate(w, h, 1); } /* If w and h not input, determine the minimum size required * to contain the origin and all c.c. */ if (w == 0 || h == 0) { boxa = pixaGetBoxa(pixa, L_CLONE); boxaGetExtent(boxa, &w, &h, NULL); boxaDestroy(&boxa); } /* Use the first pix in pixa to determine the depth. */ pixt = pixaGetPix(pixa, 0, L_CLONE); d = pixGetDepth(pixt); pixDestroy(&pixt); if ((pixd = pixCreate(w, h, d)) == NULL) return (PIX *)ERROR_PTR("pixd not made", procName, NULL); if (d > 1) pixSetAll(pixd); for (i = 0; i < n; i++) { if (pixaGetBoxGeometry(pixa, i, &xb, &yb, &wb, &hb)) { L_WARNING("no box found!", procName); continue; } pixt = pixaGetPix(pixa, i, L_CLONE); if (d == 1) pixRasterop(pixd, xb, yb, wb, hb, PIX_PAINT, pixt, 0, 0); else pixRasterop(pixd, xb, yb, wb, hb, PIX_SRC, pixt, 0, 0); pixDestroy(&pixt); } return pixd; }
main(int argc, char **argv) { char *filein, *fileout; l_float32 deg2rad; l_float32 angle, conf; PIX *pixs, *pixd; static char mainName[] = "skewtest"; if (argc != 3) exit(ERROR_INT(" Syntax: skewtest filein fileout", mainName, 1)); filein = argv[1]; fileout = argv[2]; deg2rad = 3.1415926535 / 180.; if ((pixs = pixRead(filein)) == NULL) exit(ERROR_INT("pixs not made", mainName, 1)); #if 1 pixd = pixDeskew(pixs, DESKEW_REDUCTION); pixWrite(fileout, pixd, IFF_PNG); pixDestroy(&pixd); #endif #if 0 if (pixFindSkew(pixs, &angle, &conf)) { L_WARNING("skew angle not valid", mainName); exit(1); } #endif #if 0 if (pixFindSkewSweep(pixs, &angle, SWEEP_REDUCTION, SWEEP_RANGE, SWEEP_DELTA)) { L_WARNING("skew angle not valid", mainName); exit(1); } #endif #if 0 if (pixFindSkewSweepAndSearch(pixs, &angle, &conf, SWEEP_REDUCTION2, SEARCH_REDUCTION, SWEEP_RANGE2, SWEEP_DELTA2, SEARCH_MIN_DELTA)) { L_WARNING("skew angle not valid", mainName); exit(1); } #endif pixDestroy(&pixs); exit(0); }
/*! * recogaDestroy() * * Input: &recoga (<will be set to null before returning>) * Return: void * * Notes: * (1) If a recog has a parent, the parent owns it. To destroy * a recog, it must first be "orphaned". */ void recogaDestroy(L_RECOGA **precoga) { l_int32 i; L_RECOG *recog; L_RECOGA *recoga; PROCNAME("recogaDestroy"); if (precoga == NULL) { L_WARNING("ptr address is null!\n", procName); return; } if ((recoga = *precoga) == NULL) return; rchaDestroy(&recoga->rcha); for (i = 0; i < recoga->n; i++) { if ((recog = recoga->recog[i]) == NULL) { L_ERROR("recog not found for index %d\n", procName, i); continue; } recog->parent = NULL; /* orphan it */ recogDestroy(&recog); } FREE(recoga->recog); FREE(recoga); *precoga = NULL; return; }
/*! * ptraaDestroy() * * Input: &paa (<to be nulled>) * freeflag (TRUE to free each remaining item in each ptra) * warnflag (TRUE to warn if any remaining items are not destroyed) * Return: void * * Notes: * (1) See ptraDestroy() for use of @freeflag and @warnflag. * (2) To destroy the ptraa, we destroy each ptra, then the ptr array, * then the ptraa, and then null the contents of the input ptr. */ void ptraaDestroy(L_PTRAA **ppaa, l_int32 freeflag, l_int32 warnflag) { l_int32 i, n; L_PTRA *pa; L_PTRAA *paa; PROCNAME("ptraaDestroy"); if (ppaa == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((paa = *ppaa) == NULL) return; ptraaGetSize(paa, &n); for (i = 0; i < n; i++) { pa = ptraaGetPtra(paa, i, L_REMOVE); ptraDestroy(&pa, freeflag, warnflag); } FREE(paa->ptra); FREE(paa); *ppaa = NULL; return; }
/*! * \brief boxaSelectByWHRatio() * * \param[in] boxas * \param[in] ratio width/height threshold value * \param[in] relation L_SELECT_IF_LT, L_SELECT_IF_GT, * L_SELECT_IF_LTE, L_SELECT_IF_GTE * \param[out] pchanged [optional] 1 if changed; 0 if clone returned * \return boxad filtered set, or NULL on error * * <pre> * Notes: * (1) Uses box copies in the new boxa. * (2) To keep narrow components, use relation = L_SELECT_IF_LT or * L_SELECT_IF_LTE. * To keep wide components, use relation = L_SELECT_IF_GT or * L_SELECT_IF_GTE. * </pre> */ BOXA * boxaSelectByWHRatio(BOXA *boxas, l_float32 ratio, l_int32 relation, l_int32 *pchanged) { BOXA *boxad; NUMA *na; PROCNAME("boxaSelectByWHRatio"); if (pchanged) *pchanged = FALSE; if (!boxas) return (BOXA *)ERROR_PTR("boxas not defined", procName, NULL); if (boxaGetCount(boxas) == 0) { L_WARNING("boxas is empty\n", procName); return boxaCopy(boxas, L_COPY); } if (relation != L_SELECT_IF_LT && relation != L_SELECT_IF_GT && relation != L_SELECT_IF_LTE && relation != L_SELECT_IF_GTE) return (BOXA *)ERROR_PTR("invalid relation", procName, NULL); /* Compute the indicator array for saving components */ na = boxaMakeWHRatioIndicator(boxas, ratio, relation); /* Filter to get output */ boxad = boxaSelectWithIndicator(boxas, na, pchanged); numaDestroy(&na); return boxad; }
main(int argc, char **argv) { char *filein, *fileout; char error_msg[] = " ps level = {1,2,3}; level 2 is default"; l_int32 level; PIX *pix, *pixs; static char mainName[] = "converttops"; if (argc != 3 && argc != 4) { fprintf(stderr, "Syntax: converttops filein fileout [level]\n"); fprintf(stderr, "%s\n", error_msg); return 1; } filein = argv[1]; fileout = argv[2]; level = 2; if (argc == 4) { level = atoi(argv[3]); if (level != 1 && level != 2 && level != 3) { L_WARNING("ps level must be 1, 2 or 3; setting to 2", mainName); level = 2; } } convertToPSEmbed(filein, fileout, level); return 0; }
/*! * pixaDestroy() * * Input: &pixa (<can be nulled>) * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the pixa. * (2) Always nulls the input ptr. */ void pixaDestroy(PIXA **ppixa) { l_int32 i; PIXA *pixa; PROCNAME("pixaDestroy"); if (ppixa == NULL) { L_WARNING("ptr address is NULL!", procName); return; } if ((pixa = *ppixa) == NULL) return; /* Decrement the refcount. If it is 0, destroy the pixa. */ pixaChangeRefcount(pixa, -1); if (pixa->refcount <= 0) { for (i = 0; i < pixa->n; i++) pixDestroy(&pixa->pix[i]); FREE(pixa->pix); boxaDestroy(&pixa->boxa); FREE(pixa); } *ppixa = NULL; return; }
/*! * readHeaderWebP() * * Input: filename * &w (<return> width) * &h (<return> height) * &spp (<return> spp (3 or 4)) * Return: 0 if OK, 1 on error */ l_int32 readHeaderWebP(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pspp) { l_uint8 data[100]; /* expect size info within the first 50 bytes or so */ l_int32 nbytes, bytesread; size_t filesize; FILE *fp; PROCNAME("readHeaderWebP"); if (!pw || !ph || !pspp) return ERROR_INT("input ptr(s) not defined", procName, 1); *pw = *ph = *pspp = 0; if (!filename) return ERROR_INT("filename not defined", procName, 1); /* Read no more than 100 bytes from the file */ if ((filesize = nbytesInFile(filename)) == 0) return ERROR_INT("no file size found", procName, 1); if (filesize < 100) L_WARNING("very small webp file\n", procName); nbytes = L_MIN(filesize, 100); if ((fp = fopenReadStream(filename)) == NULL) return ERROR_INT("image file not found", procName, 1); bytesread = fread((char *)data, 1, nbytes, fp); fclose(fp); if (bytesread != nbytes) return ERROR_INT("failed to read requested data", procName, 1); return readHeaderMemWebP(data, nbytes, pw, ph, pspp); }
/*! * sarrayDestroy() * * Input: &sarray <to be nulled> * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the sarray. * (2) Always nulls the input ptr. */ void sarrayDestroy(SARRAY **psa) { l_int32 i; SARRAY *sa; PROCNAME("sarrayDestroy"); if (psa == NULL) { L_WARNING("ptr address is NULL!", procName); return; } if ((sa = *psa) == NULL) return; sarrayChangeRefcount(sa, -1); if (sarrayGetRefcount(sa) <= 0) { if (sa->array) { for (i = 0; i < sa->n; i++) FREE(sa->array[i]); FREE(sa->array); } FREE(sa); } *psa = NULL; return; }
/*! * dpixDestroy() * * Input: &dpix <will be nulled> * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the dpix. * (2) Always nulls the input ptr. */ void dpixDestroy(DPIX **pdpix) { l_float64 *data; DPIX *dpix; PROCNAME("dpixDestroy"); if (!pdpix) { L_WARNING("ptr address is null!", procName); return; } if ((dpix = *pdpix) == NULL) return; /* Decrement the ref count. If it is 0, destroy the dpix. */ dpixChangeRefcount(dpix, -1); if (dpixGetRefcount(dpix) <= 0) { if ((data = dpixGetData(dpix)) != NULL) FREE(data); FREE(dpix); } *pdpix = NULL; return; }
/*! * boxaDestroy() * * Input: &boxa (<will be set to null before returning>) * Return: void * * Note: * - Decrements the ref count and, if 0, destroys the boxa. * - Always nulls the input ptr. */ void boxaDestroy(BOXA **pboxa) { l_int32 i; BOXA *boxa; PROCNAME("boxaDestroy"); if (pboxa == NULL) { L_WARNING("ptr address is null!", procName); return; } if ((boxa = *pboxa) == NULL) return; /* Decrement the ref count. If it is 0, destroy the boxa. */ boxa->refcount--; if (boxa->refcount <= 0) { for (i = 0; i < boxa->n; i++) boxDestroy(&boxa->box[i]); FREE(boxa->box); FREE(boxa); } *pboxa = NULL; return; }
/* * convertFilesToPS() * * Input: dirin (input directory) * substr (<optional> substring filter on filenames; can be NULL) * res (typ. 300 or 600 ppi) * fileout (output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) This generates a PS file for all image files in a specified * directory that contain the substr pattern to be matched. * (2) Each image is written to a separate page in the output PS file. * (3) All images are written compressed: * * if tiffg4 --> use ccittg4 * * if jpeg --> use dct * * all others --> use flate * If the image is jpeg or tiffg4, we use the existing compressed * strings for the encoding; otherwise, we read the image into * a pix and flate-encode the pieces. * (4) The resolution is often confusing. It is interpreted * as the resolution of the output display device: "If the * input image were digitized at 300 ppi, what would it * look like when displayed at res ppi." So, for example, * if res = 100 ppi, then the display pixels are 3x larger * than the 300 ppi pixels, and the image will be rendered * 3x larger. * (5) The size of the PostScript file is independent of the resolution, * because the entire file is encoded. The res parameter just * tells the PS decomposer how to render the page. Therefore, * for minimum file size without loss of visual information, * if the output res is less than 300, you should downscale * the image to the output resolution before wrapping in PS. * (6) The "canvas" on which the image is rendered, at the given * output resolution, is a standard page size (8.5 x 11 in). */ l_int32 convertFilesToPS(const char *dirin, const char *substr, l_int32 res, const char *fileout) { SARRAY *sa; PROCNAME("convertFilesToPS"); if (!dirin) return ERROR_INT("dirin not defined", procName, 1); if (!fileout) return ERROR_INT("fileout not defined", procName, 1); if (res <= 0) { L_INFO("setting res to 300 ppi", procName); res = 300; } if (res < 10 || res > 4000) L_WARNING("res is typically in the range 300-600 ppi", procName); /* Get all filtered and sorted full pathnames. */ sa = getSortedPathnamesInDirectory(dirin, substr, 0, 0); /* Generate the PS file. */ sarrayConvertFilesToPS(sa, res, fileout); sarrayDestroy(&sa); return 0; }
/* * sarrayConvertFilesToPS() * * Input: sarray (of full path names) * res (typ. 300 or 600 ppi) * fileout (output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) See convertFilesToPS() */ l_int32 sarrayConvertFilesToPS(SARRAY *sa, l_int32 res, const char *fileout) { char *fname; l_int32 i, nfiles, index, firstfile, ret, format; PROCNAME("sarrayConvertFilesToPS"); if (!sa) return ERROR_INT("sa not defined", procName, 1); if (!fileout) return ERROR_INT("fileout not defined", procName, 1); if (res <= 0) { L_INFO("setting res to 300 ppi", procName); res = 300; } if (res < 10 || res > 4000) L_WARNING("res is typically in the range 300-600 ppi", procName); nfiles = sarrayGetCount(sa); firstfile = TRUE; for (i = 0, index = 0; i < nfiles; i++) { fname = sarrayGetString(sa, i, L_NOCOPY); ret = pixReadHeader(fname, &format, NULL, NULL, NULL, NULL, NULL); if (ret) continue; if (format == IFF_UNKNOWN) continue; writeImageCompressedToPSFile(fname, fileout, res, &firstfile, &index); } return 0; }
/*! * bilateralDestroy() * * Input: &bil * Return: void */ static void bilateralDestroy(L_BILATERAL **pbil) { l_int32 i; L_BILATERAL *bil; PROCNAME("bilateralDestroy"); if (pbil == NULL) { L_WARNING("ptr address is null!\n", procName); return; } if ((bil = *pbil) == NULL) return; pixDestroy(&bil->pixs); pixDestroy(&bil->pixsc); pixaDestroy(&bil->pixac); FREE(bil->spatial); FREE(bil->range); FREE(bil->nc); FREE(bil->kindex); FREE(bil->kfract); for (i = 0; i < bil->ncomps; i++) FREE(bil->lineset[i]); FREE(bil->lineset); FREE(bil); *pbil = NULL; return; }
/*! * dewarpDestroy() * * Input: &dew (<will be set to null before returning>) * Return: void */ void dewarpDestroy(L_DEWARP **pdew) { L_DEWARP *dew; PROCNAME("dewarpDestroy"); if (pdew == NULL) { L_WARNING("ptr address is null!", procName); return; } if ((dew = *pdew) == NULL) return; pixDestroy(&dew->pixs); pixDestroy(&dew->pixd); fpixDestroy(&dew->sampvdispar); fpixDestroy(&dew->samphdispar); fpixDestroy(&dew->fullvdispar); fpixDestroy(&dew->fullhdispar); numaDestroy(&dew->naflats); numaDestroy(&dew->nacurves); FREE(dew); *pdew = NULL; return; }
/*! * pixaGetFont() * * Input: dir (directory holding pixa of character set) * fontsize (4, 6, 8, ... , 20) * &bl1 (<return> baseline of row 1) * &bl2 (<return> baseline of row 2) * &bl3 (<return> baseline of row 3) * Return: pixa of font bitmaps for 95 characters, or null on error * * Notes: * (1) This reads a pre-computed pixa file with the 95 ascii chars. */ PIXA * pixaGetFont(const char *dir, l_int32 fontsize, l_int32 *pbl0, l_int32 *pbl1, l_int32 *pbl2) { char *pathname; l_int32 fileno; PIXA *pixa; PROCNAME("pixaGetFont"); fileno = (fontsize / 2) - 2; if (fileno < 0 || fileno > NUM_FONTS) return (PIXA *)ERROR_PTR("font size invalid", procName, NULL); if (!pbl0 || !pbl1 || !pbl2) return (PIXA *)ERROR_PTR("&bl not all defined", procName, NULL); *pbl0 = baselines[fileno][0]; *pbl1 = baselines[fileno][1]; *pbl2 = baselines[fileno][2]; pathname = genPathname(dir, outputfonts[fileno]); pixa = pixaRead(pathname); FREE(pathname); if (!pixa) L_WARNING("pixa of char bitmaps not found\n", procName); return pixa; }
/*! * l_dnaDestroy() * * Input: &da (<to be nulled if it exists>) * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the l_dna. * (2) Always nulls the input ptr. */ void l_dnaDestroy(L_DNA **pda) { L_DNA *da; PROCNAME("l_dnaDestroy"); if (pda == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((da = *pda) == NULL) return; /* Decrement the ref count. If it is 0, destroy the l_dna. */ l_dnaChangeRefcount(da, -1); if (l_dnaGetRefcount(da) <= 0) { if (da->array) FREE(da->array); FREE(da); } *pda = NULL; return; }
/*! * l_byteaDestroy() * * Input: &ba (<will be set to null before returning>) * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the lba. * (2) Always nulls the input ptr. * (3) If the data has been previously removed, the lba will * have been nulled, so this will do nothing. */ void l_byteaDestroy(L_BYTEA **pba) { L_BYTEA *ba; PROCNAME("l_byteaDestroy"); if (pba == NULL) { L_WARNING("ptr address is null!", procName); return; } if ((ba = *pba) == NULL) return; /* Decrement the ref count. If it is 0, destroy the lba. */ ba->refcount--; if (ba->refcount <= 0) { if (ba->data) FREE(ba->data); FREE(ba); } *pba = NULL; return; }
/*! * gplotDestroy() * * Input: &gplot (<to be nulled>) * Return: void */ void gplotDestroy(GPLOT **pgplot) { GPLOT *gplot; PROCNAME("gplotDestroy"); if (pgplot == NULL) { L_WARNING("ptr address is null!\n", procName); return; } if ((gplot = *pgplot) == NULL) return; FREE(gplot->rootname); FREE(gplot->cmdname); sarrayDestroy(&gplot->cmddata); sarrayDestroy(&gplot->datanames); sarrayDestroy(&gplot->plotdata); sarrayDestroy(&gplot->plottitles); numaDestroy(&gplot->plotstyles); FREE(gplot->outname); if (gplot->title) FREE(gplot->title); if (gplot->xlabel) FREE(gplot->xlabel); if (gplot->ylabel) FREE(gplot->ylabel); FREE(gplot); *pgplot = NULL; return; }
/*! * pixaReadFilesSA() * * Input: sarray (full pathnames for all files) * Return: pixa, or null on error */ PIXA * pixaReadFilesSA(SARRAY *sa) { char *str; l_int32 i, n; PIX *pix; PIXA *pixa; PROCNAME("pixaReadFilesSA"); if (!sa) return (PIXA *)ERROR_PTR("sa not defined", procName, NULL); n = sarrayGetCount(sa); pixa = pixaCreate(n); for (i = 0; i < n; i++) { str = sarrayGetString(sa, i, L_NOCOPY); if ((pix = pixRead(str)) == NULL) { L_WARNING("pix not read from file %s\n", procName, str); continue; } pixaAddPix(pixa, pix, L_INSERT); } return pixa; }
/*! * kernelNormalize() * * Input: kels (source kel, to be normalized) * normsum (desired sum of elements in keld) * Return: keld (normalized version of kels), or null on error * or if sum of elements is very close to 0) * * Notes: * (1) If the sum of kernel elements is close to 0, do not * try to calculate the normalized kernel. Instead, * return a copy of the input kernel, with a warning. */ L_KERNEL * kernelNormalize(L_KERNEL *kels, l_float32 normsum) { l_int32 i, j, sx, sy, cx, cy; l_float32 sum, factor; L_KERNEL *keld; PROCNAME("kernelNormalize"); if (!kels) return (L_KERNEL *)ERROR_PTR("kels not defined", procName, NULL); kernelGetSum(kels, &sum); if (L_ABS(sum) < 0.00001) { L_WARNING("null sum; not normalizing; returning a copy\n", procName); return kernelCopy(kels); } kernelGetParameters(kels, &sy, &sx, &cy, &cx); if ((keld = kernelCreate(sy, sx)) == NULL) return (L_KERNEL *)ERROR_PTR("keld not made", procName, NULL); keld->cy = cy; keld->cx = cx; factor = normsum / sum; for (i = 0; i < sy; i++) for (j = 0; j < sx; j++) keld->data[i][j] = factor * kels->data[i][j]; return keld; }
/*! * pixaaDestroy() * * Input: &pixaa <to be nulled> * Return: void */ void pixaaDestroy(PIXAA **ppixaa) { l_int32 i; PIXAA *pixaa; PROCNAME("pixaaDestroy"); if (ppixaa == NULL) { L_WARNING("ptr address is NULL!", procName); return; } if ((pixaa = *ppixaa) == NULL) return; for (i = 0; i < pixaa->n; i++) pixaDestroy(&pixaa->pixa[i]); FREE(pixaa->pixa); boxaDestroy(&pixaa->boxa); FREE(pixaa); *ppixaa = NULL; return; }
/* * convertFilesFittedToPS() * * Input: dirin (input directory) * substr (<optional> substring filter on filenames; can be NULL) * xpts, ypts (desired size in printer points; use 0 for default) * fileout (output ps file) * Return: 0 if OK, 1 on error * * Notes: * (1) This generates a PS file for all files in a specified directory * that contain the substr pattern to be matched. * (2) Each image is written to a separate page in the output PS file. * (3) All images are written compressed: * * if tiffg4 --> use ccittg4 * * if jpeg --> use dct * * all others --> use flate * If the image is jpeg or tiffg4, we use the existing compressed * strings for the encoding; otherwise, we read the image into * a pix and flate-encode the pieces. * (4) The resolution is internally determined such that the images * are rendered, in at least one direction, at 100% of the given * size in printer points. Use 0.0 for xpts or ypts to get * the default value, which is 612.0 or 792.0, rsp. * (5) The size of the PostScript file is independent of the resolution, * because the entire file is encoded. The @xpts and @ypts * parameter tells the PS decomposer how to render the page. */ l_int32 convertFilesFittedToPS(const char *dirin, const char *substr, l_float32 xpts, l_float32 ypts, const char *fileout) { SARRAY *sa; PROCNAME("convertFilesFittedToPS"); if (!dirin) return ERROR_INT("dirin not defined", procName, 1); if (!fileout) return ERROR_INT("fileout not defined", procName, 1); if (xpts <= 0.0) { L_INFO("setting xpts to 612.0 ppi", procName); xpts = 612.0; } if (ypts <= 0.0) { L_INFO("setting ypts to 792.0 ppi", procName); ypts = 792.0; } if (xpts < 100.0 || xpts > 2000.0 || ypts < 100.0 || ypts > 2000.0) L_WARNING("xpts,ypts are typically in the range 500-800", procName); /* Get all filtered and sorted full pathnames. */ sa = getSortedPathnamesInDirectory(dirin, substr, 0, 0); /* Generate the PS file. */ sarrayConvertFilesFittedToPS(sa, xpts, ypts, fileout); sarrayDestroy(&sa); return 0; }
/*! * numaDestroy() * * Input: &na (<to be nulled if it exists>) * Return: void * * Notes: * (1) Decrements the ref count and, if 0, destroys the numa. * (2) Always nulls the input ptr. */ void numaDestroy(NUMA **pna) { NUMA *na; PROCNAME("numaDestroy"); if (pna == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((na = *pna) == NULL) return; /* Decrement the ref count. If it is 0, destroy the numa. */ numaChangeRefcount(na, -1); if (numaGetRefcount(na) <= 0) { if (na->array) LEPT_FREE(na->array); LEPT_FREE(na); } *pna = NULL; return; }