/* * 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 ); } /* ========================================================================= */