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. */
37void 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. */
64void 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 */
114void 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
161void 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
171void 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