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