1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* ---- includes ----------------------------------------------------------- */
18 
19 #include "b_BasicEm/Int16Arr.h"
20 #include "b_BasicEm/Math.h"
21 #include "b_ImageEm/HistoEq.h"
22 #include "b_ImageEm/UInt8Image.h"
23 
24 /* ---- typedefs ----------------------------------------------------------- */
25 
26 /* ---- constants ---------------------------------------------------------- */
27 
28 /* ------------------------------------------------------------------------- */
29 
30 /* ========================================================================= */
31 /*                                                                           */
32 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
33 /*                                                                           */
34 /* ========================================================================= */
35 
36 /** Computes grey level histogram of given image. */
bim_createHisto(struct bbs_Context * cpA,uint16 * histoPtrA,const struct bim_UInt8Image * imagePtrA)37 void bim_createHisto( struct bbs_Context* cpA,
38 					  uint16* histoPtrA,
39 					  const struct bim_UInt8Image* imagePtrA )
40 {
41 	uint32 iL;
42 	uint16* dstPtrL;
43 	const uint8* srcPtrL;
44 
45 	/* init histogram array with 0 */
46 	dstPtrL = histoPtrA;
47 	for( iL = 256; iL > 0; iL-- )
48 	{
49 		*dstPtrL++ = 0;
50 	}
51 
52 	/* calculate histogram */
53 	srcPtrL = imagePtrA->arrE.arrPtrE;
54 	dstPtrL = histoPtrA;
55 	for( iL = imagePtrA->arrE.sizeE; iL > 0; iL-- )
56 	{
57 		dstPtrL[ *srcPtrL++ ]++;
58 	}
59 }
60 
61 /* ------------------------------------------------------------------------- */
62 
63 /** Computes grey level histogram of given image. */
bim_createHistoOfSection(struct bbs_Context * cpA,uint16 * histoPtrA,const struct bts_Int16Rect * sectionPtrA,const struct bim_UInt8Image * imagePtrA)64 void bim_createHistoOfSection( struct bbs_Context* cpA,
65 							   uint16* histoPtrA,
66 							   const struct bts_Int16Rect* sectionPtrA,
67 							   const struct bim_UInt8Image* imagePtrA )
68 {
69 	uint32 xL, yL;
70 	const uint8* srcPtrL;
71 	uint16* dstPtrL;
72 	struct bts_Int16Rect sectionL = *sectionPtrA;
73 	uint32 sectWidthL;
74 	uint32 sectHeightL;
75 	int32 imgWidthL = imagePtrA->widthE;
76 	int32 imgHeightL = imagePtrA->heightE;
77 
78 	/* adjustments */
79 	sectionL.x1E = bbs_max( 0, sectionL.x1E );
80 	sectionL.x1E = bbs_min( imgWidthL, sectionL.x1E );
81 	sectionL.x2E = bbs_max( 0, sectionL.x2E );
82 	sectionL.x2E = bbs_min( imgWidthL, sectionL.x2E );
83 	sectionL.y1E = bbs_max( 0, sectionL.y1E );
84 	sectionL.y1E = bbs_min( imgHeightL, sectionL.y1E );
85 	sectionL.y2E = bbs_max( 0, sectionL.y2E );
86 	sectionL.y2E = bbs_min( imgHeightL, sectionL.y2E );
87 
88 	sectWidthL = sectionL.x2E - sectionL.x1E;
89 	sectHeightL = sectionL.y2E - sectionL.y1E;
90 
91 	/* init histogram with 0 */
92 	dstPtrL = histoPtrA;
93 	for( xL = 256; xL > 0; xL-- )
94 	{
95 		*dstPtrL++ = 0;
96 	}
97 
98 	/* calculate histogram */
99 	srcPtrL = imagePtrA->arrE.arrPtrE + sectionL.y1E * imgWidthL + sectionL.x1E;
100 	dstPtrL = histoPtrA;
101 	for( yL = 0; yL < sectHeightL; yL++ )
102 	{
103 		for( xL = 0; xL < sectWidthL; xL++ )
104 		{
105 			dstPtrL[ *srcPtrL++ ]++;
106 		}
107 		srcPtrL += imgWidthL - sectWidthL;
108 	}
109 }
110 
111 /* ------------------------------------------------------------------------- */
112 
113 /** equalize image using given histogram */
bim_equalize(struct bbs_Context * cpA,struct bim_UInt8Image * imagePtrA,const uint16 * histoPtrA)114 void bim_equalize( struct bbs_Context* cpA,
115 				   struct bim_UInt8Image* imagePtrA,
116 				   const uint16* histoPtrA )
117 {
118 	uint32 kL;
119 	uint32 sumL = 0;
120 	uint32 totalSumL = 0;
121 	const uint16* histoArrPtrL;
122 	uint8* dstPtrL;
123 	uint8 mappingL[ 256 ];
124 
125 	/* determine number of counts in histogram */
126 	histoArrPtrL = histoPtrA;
127 	for( kL = 256; kL > 0; kL-- )
128 	{
129 		totalSumL += *histoArrPtrL++;
130 	}
131 
132 	if( totalSumL == 0 ) totalSumL = 1;
133 
134 	/* compute transfer function (cumulative histogram) */
135 	histoArrPtrL = histoPtrA;
136 	for( kL = 0; kL < 256; kL++ )
137 	{
138 		sumL += *histoArrPtrL++;
139 		mappingL[ kL ] = ( sumL * 255 ) / totalSumL;
140 	}
141 
142 	/* remap pixel values */
143 	dstPtrL = imagePtrA->arrE.arrPtrE;
144 	for( kL = imagePtrA->arrE.sizeE; kL > 0; kL-- )
145 	{
146 		*dstPtrL = mappingL[ *dstPtrL ];
147 		dstPtrL++;
148 	}
149 }
150 
151 /* ------------------------------------------------------------------------- */
152 
153 /* ========================================================================= */
154 /*                                                                           */
155 /* ---- \ghd{ external functions } ----------------------------------------- */
156 /*                                                                           */
157 /* ========================================================================= */
158 
159 /* ------------------------------------------------------------------------- */
160 
bim_UInt8Image_equalize(struct bbs_Context * cpA,struct bim_UInt8Image * imagePtrA)161 void bim_UInt8Image_equalize( struct bbs_Context* cpA,
162 							  struct bim_UInt8Image* imagePtrA )
163 {
164 	uint16 histogramL[ 256 ];
165 	bim_createHisto( cpA, histogramL, imagePtrA );
166 	bim_equalize( cpA, imagePtrA, histogramL );
167 }
168 
169 /* ------------------------------------------------------------------------- */
170 
bim_UInt8Image_equalizeSection(struct bbs_Context * cpA,struct bim_UInt8Image * imagePtrA,const struct bts_Int16Rect * sectionPtrA)171 void bim_UInt8Image_equalizeSection( struct bbs_Context* cpA,
172 									 struct bim_UInt8Image* imagePtrA,
173 									 const struct bts_Int16Rect* sectionPtrA )
174 {
175 	uint16 histogramL[ 256 ];
176 	bim_createHistoOfSection( cpA, histogramL, sectionPtrA, imagePtrA );
177 	bim_equalize( cpA, imagePtrA, histogramL );
178 }
179 
180 /* ========================================================================= */
181