blob: 0b73b21d996b26048370ae10eaf799935b7f77fe [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ---- includes ----------------------------------------------------------- */
#include "b_BasicEm/Int16Arr.h"
#include "b_BasicEm/Math.h"
#include "b_ImageEm/HistoEq.h"
#include "b_ImageEm/UInt8Image.h"
/* ---- typedefs ----------------------------------------------------------- */
/* ---- constants ---------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
/* */
/* ---- \ghd{ auxiliary functions } ---------------------------------------- */
/* */
/* ========================================================================= */
/** Computes grey level histogram of given image. */
void bim_createHisto( struct bbs_Context* cpA,
uint16* histoPtrA,
const struct bim_UInt8Image* imagePtrA )
{
uint32 iL;
uint16* dstPtrL;
const uint8* srcPtrL;
/* init histogram array with 0 */
dstPtrL = histoPtrA;
for( iL = 256; iL > 0; iL-- )
{
*dstPtrL++ = 0;
}
/* calculate histogram */
srcPtrL = imagePtrA->arrE.arrPtrE;
dstPtrL = histoPtrA;
for( iL = imagePtrA->arrE.sizeE; iL > 0; iL-- )
{
dstPtrL[ *srcPtrL++ ]++;
}
}
/* ------------------------------------------------------------------------- */
/** Computes grey level histogram of given image. */
void bim_createHistoOfSection( struct bbs_Context* cpA,
uint16* histoPtrA,
const struct bts_Int16Rect* sectionPtrA,
const struct bim_UInt8Image* imagePtrA )
{
uint32 xL, yL;
const uint8* srcPtrL;
uint16* dstPtrL;
struct bts_Int16Rect sectionL = *sectionPtrA;
uint32 sectWidthL;
uint32 sectHeightL;
int32 imgWidthL = imagePtrA->widthE;
int32 imgHeightL = imagePtrA->heightE;
/* adjustments */
sectionL.x1E = bbs_max( 0, sectionL.x1E );
sectionL.x1E = bbs_min( imgWidthL, sectionL.x1E );
sectionL.x2E = bbs_max( 0, sectionL.x2E );
sectionL.x2E = bbs_min( imgWidthL, sectionL.x2E );
sectionL.y1E = bbs_max( 0, sectionL.y1E );
sectionL.y1E = bbs_min( imgHeightL, sectionL.y1E );
sectionL.y2E = bbs_max( 0, sectionL.y2E );
sectionL.y2E = bbs_min( imgHeightL, sectionL.y2E );
sectWidthL = sectionL.x2E - sectionL.x1E;
sectHeightL = sectionL.y2E - sectionL.y1E;
/* init histogram with 0 */
dstPtrL = histoPtrA;
for( xL = 256; xL > 0; xL-- )
{
*dstPtrL++ = 0;
}
/* calculate histogram */
srcPtrL = imagePtrA->arrE.arrPtrE + sectionL.y1E * imgWidthL + sectionL.x1E;
dstPtrL = histoPtrA;
for( yL = 0; yL < sectHeightL; yL++ )
{
for( xL = 0; xL < sectWidthL; xL++ )
{
dstPtrL[ *srcPtrL++ ]++;
}
srcPtrL += imgWidthL - sectWidthL;
}
}
/* ------------------------------------------------------------------------- */
/** equalize image using given histogram */
void bim_equalize( struct bbs_Context* cpA,
struct bim_UInt8Image* imagePtrA,
const uint16* histoPtrA )
{
uint32 kL;
uint32 sumL = 0;
uint32 totalSumL = 0;
const uint16* histoArrPtrL;
uint8* dstPtrL;
uint8 mappingL[ 256 ];
/* determine number of counts in histogram */
histoArrPtrL = histoPtrA;
for( kL = 256; kL > 0; kL-- )
{
totalSumL += *histoArrPtrL++;
}
if( totalSumL == 0 ) totalSumL = 1;
/* compute transfer function (cumulative histogram) */
histoArrPtrL = histoPtrA;
for( kL = 0; kL < 256; kL++ )
{
sumL += *histoArrPtrL++;
mappingL[ kL ] = ( sumL * 255 ) / totalSumL;
}
/* remap pixel values */
dstPtrL = imagePtrA->arrE.arrPtrE;
for( kL = imagePtrA->arrE.sizeE; kL > 0; kL-- )
{
*dstPtrL = mappingL[ *dstPtrL ];
dstPtrL++;
}
}
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
/* */
/* ---- \ghd{ external functions } ----------------------------------------- */
/* */
/* ========================================================================= */
/* ------------------------------------------------------------------------- */
void bim_UInt8Image_equalize( struct bbs_Context* cpA,
struct bim_UInt8Image* imagePtrA )
{
uint16 histogramL[ 256 ];
bim_createHisto( cpA, histogramL, imagePtrA );
bim_equalize( cpA, imagePtrA, histogramL );
}
/* ------------------------------------------------------------------------- */
void bim_UInt8Image_equalizeSection( struct bbs_Context* cpA,
struct bim_UInt8Image* imagePtrA,
const struct bts_Int16Rect* sectionPtrA )
{
uint16 histogramL[ 256 ];
bim_createHistoOfSection( cpA, histogramL, sectionPtrA, imagePtrA );
bim_equalize( cpA, imagePtrA, histogramL );
}
/* ========================================================================= */