Пример #1
0
/*!
 *  pixResizeImageData()
 *
 *      Input:  pixd (gets new uninitialized buffer for image data)
 *              pixs (determines the size of the buffer; not changed)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This removes any existing image data from pixd and
 *          allocates an uninitialized buffer that will hold the
 *          amount of image data that is in pixs.
 */
l_int32
pixResizeImageData(PIX  *pixd,
                   PIX  *pixs)
{
l_int32    w, h, d, wpl, bytes;
l_uint32  *data;

    PROCNAME("pixResizeImageData");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixd)
        return ERROR_INT("pixd not defined", procName, 1);

    if (pixSizesEqual(pixs, pixd))  /* nothing to do */
        return 0;

    pixGetDimensions(pixs, &w, &h, &d);
    wpl = pixGetWpl(pixs);
    pixSetWidth(pixd, w);
    pixSetHeight(pixd, h);
    pixSetDepth(pixd, d);
    pixSetWpl(pixd, wpl);
    bytes = 4 * wpl * h;
    pixFreeData(pixd);  /* free any existing image data */
    if ((data = (l_uint32 *)pix_malloc(bytes)) == NULL)
        return ERROR_INT("pix_malloc fail for data", procName, 1);
    pixSetData(pixd, data);
    return 0;
}
Пример #2
0
/*!
 *  pixTransferAllData()
 *
 *      Input:  pixd (must be different from pixs)
 *              &pixs (will be nulled if refcount goes to 0)
 *              copytext (1 to copy the text field; 0 to skip)
 *              copyformat (1 to copy the informat field; 0 to skip)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This does a complete data transfer from pixs to pixd,
 *          followed by the destruction of pixs (refcount permitting).
 *      (2) If the refcount of pixs is 1, pixs is destroyed.  Otherwise,
 *          the data in pixs is copied (rather than transferred) to pixd.
 *      (3) This operation, like all others with a pre-existing pixd,
 *          will side-effect any existing clones of pixd.  The pixd
 *          refcount does not change.
 *      (4) When might you use this?  Suppose you have an in-place Pix
 *          function (returning void) with the typical signature:
 *              void function-inplace(PIX *pix, ...)
 *          where "..." are non-pointer input parameters, and suppose
 *          further that you sometimes want to return an arbitrary Pix
 *          in place of the input Pix.  There are two ways you can do this:
 *          (a) The straightforward way is to change the function
 *              signature to take the address of the Pix ptr:
 *                  void function-inplace(PIX **ppix, ...) {
 *                      PIX *pixt = function-makenew(*ppix);
 *                      pixDestroy(ppix);
 *                      *ppix = pixt;
 *                      return;
 *                  }
 *              Here, the input and returned pix are different, as viewed
 *              by the calling function, and the inplace function is
 *              expected to destroy the input pix to avoid a memory leak.
 *          (b) Keep the signature the same and use pixTransferAllData()
 *              to return the new Pix in the input Pix struct:
 *                  void function-inplace(PIX *pix, ...) {
 *                      PIX *pixt = function-makenew(pix);
 *                      pixTransferAllData(pix, &pixt);  // pixt is destroyed
 *                      return;
 *                  }
 *              Here, the input and returned pix are the same, as viewed
 *              by the calling function, and the inplace function must
 *              never destroy the input pix, because the calling function
 *              maintains an unchanged handle to it.
 */
l_int32
pixTransferAllData(PIX     *pixd,
                   PIX    **ppixs,
                   l_int32  copytext,
                   l_int32  copyformat)
{
l_int32  nbytes;
PIX     *pixs;

    PROCNAME("pixTransferAllData");

    if (!ppixs)
        return ERROR_INT("&pixs not defined", procName, 1);
    if ((pixs = *ppixs) == NULL)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!pixd)
        return ERROR_INT("pixd not defined", procName, 1);
    if (pixs == pixd)  /* no-op */
        return ERROR_INT("pixd == pixs", procName, 1);

    if (pixGetRefcount(pixs) == 1) {  /* transfer the data, cmap, text */
        pixFreeData(pixd);  /* dealloc any existing data */
        pixSetData(pixd, pixGetData(pixs));  /* transfer new data from pixs */
        pixs->data = NULL;  /* pixs no longer owns data */
        pixSetColormap(pixd, pixGetColormap(pixs));  /* frees old; sets new */
        pixs->colormap = NULL;  /* pixs no longer owns colormap */
        if (copytext) {
            pixSetText(pixd, pixGetText(pixs));
            pixSetText(pixs, NULL);
        }
    } else {  /* preserve pixs by making a copy of the data, cmap, text */
        pixResizeImageData(pixd, pixs);
        nbytes = 4 * pixGetWpl(pixs) * pixGetHeight(pixs);
        memcpy((char *)pixGetData(pixd), (char *)pixGetData(pixs), nbytes);
        pixCopyColormap(pixd, pixs);
        if (copytext)
            pixCopyText(pixd, pixs);
    }
  
    pixCopyResolution(pixd, pixs);
    pixCopyDimensions(pixd, pixs);
    if (copyformat)
        pixCopyInputFormat(pixd, pixs);

        /* This will destroy pixs if data was transferred;
         * otherwise, it just decrements its refcount. */
    pixDestroy(ppixs);
    return 0;
}
Пример #3
0
main(int    argc,
     char **argv)
{
l_int32      error;
l_uint32    *data;
PIX         *pix1, *pix2, *pix3, *pix1c, *pix2c, *pix1t, *pix2t, *pixd;
PIXA        *pixa;
static char  mainName[] = "pixmem_reg";

    error = 0;
    pixa = pixaCreate(0);

        /* Copy with internal resizing: onto a cmapped image */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    fprintf(stderr, "before copy 2 --> 3\n");
    pixCopy(pix3, pix2);
    Compare(pix2, pix3, &error);
    pixSaveTiled(pix3, pixa, 4, 1, 30, 32);
    fprintf(stderr, "before copy 3 --> 1\n");
    pixCopy(pix1, pix3);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix1, pixa, 4, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Copy with internal resizing: from a cmapped image */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    fprintf(stderr, "before copy 1 --> 2\n");
    pixCopy(pix2, pix1);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 1, 30, 32);
    fprintf(stderr, "before copy 2 --> 3\n");
    pixCopy(pix3, pix2);
    Compare(pix3, pix2, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Transfer of data pixs --> pixd, when pixs is not cloned.
         * pixs is destroyed.  */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixCopy(NULL, pix1);
    fprintf(stderr, "before transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1, 0, 0);
    Compare(pix2, pix1c, &error);
    pixSaveTiled(pix2, pixa, 1, 1, 30, 32);
    fprintf(stderr, "before transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2, 0, 0);
    Compare(pix3, pix1c, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1c);
    pixDestroy(&pix3);

        /* Another transfer of data pixs --> pixd, when pixs is not cloned.
         * pixs is destroyed. */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixCopy(NULL, pix1);
    pix2c = pixCopy(NULL, pix2);
    fprintf(stderr, "before copy transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1c, 0, 0);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 0, 30, 32);
    fprintf(stderr, "before copy transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2, 0, 0);
    Compare(pix3, pix1, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2c);
    pixDestroy(&pix3);

        /* Transfer of data pixs --> pixd, when pixs is cloned.
         * pixs has its refcount reduced by 1. */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixClone(pix1);
    pix2c = pixClone(pix2);
    fprintf(stderr, "before clone transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1c, 0, 0);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 0, 30, 32);
    fprintf(stderr, "before clone transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2c, 0, 0);
    Compare(pix3, pix1, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Extraction of data when pixs is not cloned, putting
         * the data into a new template of pixs. */
    pix2 = pixRead("feyn-fract.tif");
    fprintf(stderr, "no clone: before extraction and reinsertion of 2\n");
    pix2c = pixCopy(NULL, pix2);  /* for later reference */
    data = pixExtractData(pix2);
    pix2t = pixCreateTemplateNoInit(pix2);
    pixFreeData(pix2t);
    pixSetData(pix2t, data);
    Compare(pix2c, pix2t, &error);
    pixSaveTiled(pix2t, pixa, 4, 1, 30, 32);
    pixDestroy(&pix2);
    pixDestroy(&pix2c);
    pixDestroy(&pix2t);

        /* Extraction of data when pixs is cloned, putting
         * a copy of the data into a new template of pixs. */
    pix1 = pixRead("weasel4.16c.png");
    fprintf(stderr, "clone: before extraction and reinsertion of 1\n");
    pix1c = pixClone(pix1);  /* bump refcount of pix1 to 2 */
    data = pixExtractData(pix1);  /* should make a copy of data */
    pix1t = pixCreateTemplateNoInit(pix1);
    pixFreeData(pix1t);
    pixSetData(pix1t, data);
    Compare(pix1c, pix1t, &error);
    pixSaveTiled(pix1t, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix1c);
    pixDestroy(&pix1t);

    pixd = pixaDisplay(pixa, 0, 0);
    pixDisplay(pixd, 100, 100);
    pixWrite("/tmp/junkpixmem.png", pixd, IFF_PNG);
    pixaDestroy(&pixa);
    pixDestroy(&pixd);

    if (error)
        fprintf(stderr, "Fail: an error occurred\n");
    else
        fprintf(stderr, "Success: no errors\n");
    return 0;
}