twain3.0/3rdparty/hgOCR/leptonica/pixacc.c

355 lines
9.4 KiB
C
Raw Normal View History

2021-11-20 06:24:33 +00:00
/*====================================================================*
- Copyright (C) 2001 Leptonica. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials
- provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================*/
/*!
* \file pixacc.c
* <pre>
*
* Pixacc creation, destruction
* PIXACC *pixaccCreate()
* PIXACC *pixaccCreateFromPix()
* void pixaccDestroy()
*
* Pixacc finalization
* PIX *pixaccFinal()
*
* Pixacc accessors
* PIX *pixaccGetPix()
* l_int32 pixaccGetOffset()
*
* Pixacc accumulators
* l_int32 pixaccAdd()
* l_int32 pixaccSubtract()
* l_int32 pixaccMultConst()
* l_int32 pixaccMultConstAccumulate()
*
* This is a simple interface for some of the pixel arithmetic operations
* in pixarith.c. These are easy to code up, but not as fast as
* hand-coded functions that do arithmetic on corresponding pixels.
*
* Suppose you want to make a linear combination of pix1 and pix2:
* pixd = 0.4 * pix1 + 0.6 * pix2
* where pix1 and pix2 are the same size and have depth 'd'. Then:
* Pixacc *pacc = pixaccCreateFromPix(pix1, 0); // first; addition only
* pixaccMultConst(pacc, 0.4);
* pixaccMultConstAccumulate(pacc, pix2, 0.6); // Add in 0.6 of the second
* pixd = pixaccFinal(pacc, d); // Get the result
* pixaccDestroy(&pacc);
* </pre>
*/
#include "allheaders.h"
/*---------------------------------------------------------------------*
* Pixacc creation, destruction *
*---------------------------------------------------------------------*/
/*!
* \brief pixaccCreate()
*
* \param[in] w, h of 32 bpp internal Pix
* \param[in] negflag 0 if only positive numbers are involved;
* 1 if there will be negative numbers
* \return pixacc, or NULL on error
*
* <pre>
* Notes:
* (1) Use %negflag = 1 for safety if any negative numbers are going
* to be used in the chain of operations. Negative numbers
* arise, e.g., by subtracting a pix, or by adding a pix
* that has been pre-multiplied by a negative number.
* (2) Initializes the internal 32 bpp pix, similarly to the
* initialization in pixInitAccumulate().
* </pre>
*/
PIXACC *
pixaccCreate(l_int32 w,
l_int32 h,
l_int32 negflag)
{
PIXACC *pixacc;
PROCNAME("pixaccCreate");
if ((pixacc = (PIXACC *)LEPT_CALLOC(1, sizeof(PIXACC))) == NULL)
return (PIXACC *)ERROR_PTR("pixacc not made", procName, NULL);
pixacc->w = w;
pixacc->h = h;
if ((pixacc->pix = pixCreate(w, h, 32)) == NULL) {
pixaccDestroy(&pixacc);
return (PIXACC *)ERROR_PTR("pix not made", procName, NULL);
}
if (negflag) {
pixacc->offset = 0x40000000;
pixSetAllArbitrary(pixacc->pix, pixacc->offset);
}
return pixacc;
}
/*!
* \brief pixaccCreateFromPix()
*
* \param[in] pix
* \param[in] negflag 0 if only positive numbers are involved;
* 1 if there will be negative numbers
* \return pixacc, or NULL on error
*
* <pre>
* Notes:
* (1) See pixaccCreate()
* </pre>
*/
PIXACC *
pixaccCreateFromPix(PIX *pix,
l_int32 negflag)
{
l_int32 w, h;
PIXACC *pixacc;
PROCNAME("pixaccCreateFromPix");
if (!pix)
return (PIXACC *)ERROR_PTR("pix not defined", procName, NULL);
pixGetDimensions(pix, &w, &h, NULL);
pixacc = pixaccCreate(w, h, negflag);
pixaccAdd(pixacc, pix);
return pixacc;
}
/*!
* \brief pixaccDestroy()
*
* \param[in,out] ppixacc will be set to null before returning
* \return void
*
* <pre>
* Notes:
* (1) Always nulls the input ptr.
* </pre>
*/
void
pixaccDestroy(PIXACC **ppixacc)
{
PIXACC *pixacc;
PROCNAME("pixaccDestroy");
if (ppixacc == NULL) {
L_WARNING("ptr address is NULL!", procName);
return;
}
if ((pixacc = *ppixacc) == NULL)
return;
pixDestroy(&pixacc->pix);
LEPT_FREE(pixacc);
*ppixacc = NULL;
return;
}
/*---------------------------------------------------------------------*
* Pixacc finalization *
*---------------------------------------------------------------------*/
/*!
* \brief pixaccFinal()
*
* \param[in] pixacc
* \param[in] outdepth 8, 16 or 32 bpp
* \return pixd 8, 16 or 32 bpp, or NULL on error
*/
PIX *
pixaccFinal(PIXACC *pixacc,
l_int32 outdepth)
{
PROCNAME("pixaccFinal");
if (!pixacc)
return (PIX *)ERROR_PTR("pixacc not defined", procName, NULL);
return pixFinalAccumulate(pixaccGetPix(pixacc), pixaccGetOffset(pixacc),
outdepth);
}
/*---------------------------------------------------------------------*
* Pixacc accessors *
*---------------------------------------------------------------------*/
/*!
* \brief pixaccGetPix()
*
* \param[in] pixacc
* \return pix, or NULL on error
*/
PIX *
pixaccGetPix(PIXACC *pixacc)
{
PROCNAME("pixaccGetPix");
if (!pixacc)
return (PIX *)ERROR_PTR("pixacc not defined", procName, NULL);
return pixacc->pix;
}
/*!
* \brief pixaccGetOffset()
*
* \param[in] pixacc
* \return offset, or -1 on error
*/
l_int32
pixaccGetOffset(PIXACC *pixacc)
{
PROCNAME("pixaccGetOffset");
if (!pixacc)
return ERROR_INT("pixacc not defined", procName, -1);
return pixacc->offset;
}
/*---------------------------------------------------------------------*
* Pixacc accumulators *
*---------------------------------------------------------------------*/
/*!
* \brief pixaccAdd()
*
* \param[in] pixacc
* \param[in] pix to be added
* \return 0 if OK, 1 on error
*/
l_ok
pixaccAdd(PIXACC *pixacc,
PIX *pix)
{
PROCNAME("pixaccAdd");
if (!pixacc)
return ERROR_INT("pixacc not defined", procName, 1);
if (!pix)
return ERROR_INT("pix not defined", procName, 1);
pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_ADD);
return 0;
}
/*!
* \brief pixaccSubtract()
*
* \param[in] pixacc
* \param[in] pix to be subtracted
* \return 0 if OK, 1 on error
*/
l_ok
pixaccSubtract(PIXACC *pixacc,
PIX *pix)
{
PROCNAME("pixaccSubtract");
if (!pixacc)
return ERROR_INT("pixacc not defined", procName, 1);
if (!pix)
return ERROR_INT("pix not defined", procName, 1);
pixAccumulate(pixaccGetPix(pixacc), pix, L_ARITH_SUBTRACT);
return 0;
}
/*!
* \brief pixaccMultConst()
*
* \param[in] pixacc
* \param[in] factor
* \return 0 if OK, 1 on error
*/
l_ok
pixaccMultConst(PIXACC *pixacc,
l_float32 factor)
{
PROCNAME("pixaccMultConst");
if (!pixacc)
return ERROR_INT("pixacc not defined", procName, 1);
pixMultConstAccumulate(pixaccGetPix(pixacc), factor,
pixaccGetOffset(pixacc));
return 0;
}
/*!
* \brief pixaccMultConstAccumulate()
*
* \param[in] pixacc
* \param[in] pix
* \param[in] factor
* \return 0 if OK, 1 on error
*
* <pre>
* Notes:
* (1) This creates a temp pix that is %pix multiplied by the
* constant %factor. It then adds that into %pixacc.
* </pre>
*/
l_ok
pixaccMultConstAccumulate(PIXACC *pixacc,
PIX *pix,
l_float32 factor)
{
l_int32 w, h, d, negflag;
PIX *pixt;
PIXACC *pacct;
PROCNAME("pixaccMultConstAccumulate");
if (!pixacc)
return ERROR_INT("pixacc not defined", procName, 1);
if (!pix)
return ERROR_INT("pix not defined", procName, 1);
if (factor == 0.0) return 0;
pixGetDimensions(pix, &w, &h, &d);
negflag = (factor > 0.0) ? 0 : 1;
pacct = pixaccCreate(w, h, negflag);
pixaccAdd(pacct, pix);
pixaccMultConst(pacct, factor);
pixt = pixaccFinal(pacct, d);
pixaccAdd(pixacc, pixt);
pixaccDestroy(&pacct);
pixDestroy(&pixt);
return 0;
}