1 # include "bitmapConfig.h"
2
3 # include <stdlib.h>
4
5 # include "bitmap.h"
6
7 # include <appDebugon.h>
8
bmAverageMono8Row(const BitmapDescription * bdOut,const BitmapDescription * bdIn,unsigned char * to,const unsigned char * rf,int xpixels,int ypixels)9 static void bmAverageMono8Row( const BitmapDescription * bdOut,
10 const BitmapDescription * bdIn,
11 unsigned char * to,
12 const unsigned char * rf,
13 int xpixels,
14 int ypixels )
15 {
16 int col;
17
18 int r;
19 int c;
20
21 for ( col= 0; col < bdIn->bdPixelsWide/ xpixels; rf += xpixels, col++ )
22 {
23 int v= 0;
24 const int n= xpixels* ypixels;
25 const unsigned char * cf= rf;
26
27 for ( r= 0; r < ypixels; cf += bdIn->bdBytesPerRow, r++ )
28 {
29 const unsigned char * f= cf;
30
31 for ( c= 0; c < xpixels; c++ )
32 { v += *(f++); }
33 }
34
35 *(to++)= ( v+ n/2 )/ n;
36 }
37
38 xpixels= bdIn->bdPixelsWide % xpixels;
39
40 if ( xpixels > 0 )
41 {
42 int v= 0;
43 const int n= ypixels* xpixels;
44 const unsigned char * cf= rf;
45
46 for ( r= 0; r < ypixels; cf += bdIn->bdBytesPerRow, r++ )
47 {
48 const unsigned char * f= cf;
49
50 for ( c= 0; c < xpixels; c++ )
51 { v += *(f++); }
52 }
53
54 *(to++)= ( v+ n/2 )/ n;
55 }
56
57 return;
58 }
59
bmAverageMono8Image(const BitmapDescription * bdOut,const BitmapDescription * bdIn,unsigned char * buffer,const unsigned char * bufIn,int xpixels,int ypixels)60 static void bmAverageMono8Image(
61 const BitmapDescription * bdOut,
62 const BitmapDescription * bdIn,
63 unsigned char * buffer,
64 const unsigned char * bufIn,
65 int xpixels,
66 int ypixels )
67 {
68 int row;
69 unsigned char * to= buffer;
70 int ytail= bdIn->bdPixelsHigh % ypixels;
71
72 for ( row= 0; row < bdIn->bdPixelsHigh/ ypixels; row++ )
73 {
74 const unsigned char * rf= bufIn+ ypixels* row* bdIn->bdBytesPerRow;
75
76 bmAverageMono8Row( bdOut, bdIn, to, rf, xpixels, ypixels );
77
78 to += bdOut->bdBytesPerRow;
79 }
80
81 if ( ytail > 0 )
82 {
83 const unsigned char * rf= bufIn+ ypixels* row* bdIn->bdBytesPerRow;
84
85 bmAverageMono8Row( bdOut, bdIn, to, rf, xpixels, ytail );
86 }
87
88 return;
89 }
90
bmAverageRgb24Row(const BitmapDescription * bdOut,const BitmapDescription * bdIn,unsigned char * to,const unsigned char * rf,int xpixels,int ypixels)91 static void bmAverageRgb24Row( const BitmapDescription * bdOut,
92 const BitmapDescription * bdIn,
93 unsigned char * to,
94 const unsigned char * rf,
95 int xpixels,
96 int ypixels )
97 {
98 int col;
99
100 int r;
101 int c;
102
103 for ( col= 0; col < bdIn->bdPixelsWide/ xpixels; rf += 3* xpixels, col++ )
104 {
105 int rv= 0;
106 int gv= 0;
107 int bv= 0;
108 const int n= xpixels* ypixels;
109 const unsigned char * cf= rf;
110
111 for ( r= 0; r < ypixels; cf += bdIn->bdBytesPerRow, r++ )
112 {
113 const unsigned char * f= cf;
114
115 for ( c= 0; c < xpixels; c++ )
116 { rv += *(f++); gv += *(f++); bv += *(f++); }
117 }
118
119 *(to++)= ( rv+ n/2 )/ n;
120 *(to++)= ( gv+ n/2 )/ n;
121 *(to++)= ( bv+ n/2 )/ n;
122 }
123
124 xpixels= bdIn->bdPixelsWide % xpixels;
125
126 if ( xpixels > 0 )
127 {
128 int rv= 0;
129 int gv= 0;
130 int bv= 0;
131 const int n= ypixels* xpixels;
132 const unsigned char * cf= rf;
133
134 for ( r= 0; r < ypixels; cf += bdIn->bdBytesPerRow, r++ )
135 {
136 const unsigned char * f= cf;
137
138 for ( c= 0; c < xpixels; c++ )
139 { rv += *(f++); gv += *(f++); bv += *(f++); }
140 }
141
142 *(to++)= ( rv+ n/2 )/ n;
143 *(to++)= ( gv+ n/2 )/ n;
144 *(to++)= ( bv+ n/2 )/ n;
145 }
146
147 return;
148 }
149
bmAverageRgb24Image(const BitmapDescription * bdOut,const BitmapDescription * bdIn,unsigned char * buffer,const unsigned char * bufIn,int xpixels,int ypixels)150 static void bmAverageRgb24Image(
151 const BitmapDescription * bdOut,
152 const BitmapDescription * bdIn,
153 unsigned char * buffer,
154 const unsigned char * bufIn,
155 int xpixels,
156 int ypixels )
157 {
158 int row;
159 unsigned char * to= buffer;
160 int ytail= bdIn->bdPixelsHigh % ypixels;
161
162 for ( row= 0; row < bdIn->bdPixelsHigh/ ypixels; row++ )
163 {
164 const unsigned char * rf= bufIn+ ypixels* row* bdIn->bdBytesPerRow;
165
166 bmAverageRgb24Row( bdOut, bdIn, to, rf, xpixels, ypixels );
167
168 to += bdOut->bdBytesPerRow;
169 }
170
171 if ( ytail > 0 )
172 {
173 const unsigned char * rf= bufIn+ ypixels* row* bdIn->bdBytesPerRow;
174
175 bmAverageRgb24Row( bdOut, bdIn, to, rf, xpixels, ytail );
176 }
177
178 return;
179 }
180
bmAverage(RasterImage * riOut,const RasterImage * riIn,int xpixels,int ypixels)181 int bmAverage( RasterImage * riOut,
182 const RasterImage * riIn,
183 int xpixels,
184 int ypixels )
185 {
186 const BitmapDescription * bdIn= &(riIn->riDescription);
187 int rval= 0;
188
189 RasterImage ri;
190
191 bmInitRasterImage( &ri );
192
193 switch( bdIn->bdColorEncoding )
194 {
195 case BMcoBLACKWHITE:
196 case BMcoWHITEBLACK:
197 case BMcoRGB:
198 break;
199 case BMcoRGB8PALETTE:
200 default:
201 LDEB(bdIn->bdColorEncoding);
202 rval= -1; goto ready;
203 }
204
205 switch( bdIn->bdBitsPerSample )
206 {
207 case 8:
208 break;
209 default:
210 LDEB(bdIn->bdBitsPerSample); rval= -1; goto ready;
211 }
212
213 /************************************************************/
214 /* Derive properties of output bitmap from input. */
215 /************************************************************/
216 if ( bmCopyDescription( &(ri.riDescription), bdIn ) )
217 { LDEB(1); rval= -1; goto ready; }
218
219 ri.riDescription.bdPixelsWide= ( bdIn->bdPixelsWide+ xpixels- 1 )/xpixels;
220 ri.riDescription.bdPixelsHigh= ( bdIn->bdPixelsHigh+ ypixels- 1 )/ypixels;
221
222 if ( bmCalculateSizes( &(ri.riDescription) ) )
223 { LDEB(1); rval= -1; goto ready; }
224
225 if ( bmAllocateBuffer( &ri ) )
226 { LLDEB(ri.riDescription.bdBufferLength,ri.riBytes); rval= -1; goto ready; }
227
228 /************************************************************/
229 /* Average pixel values. */
230 /************************************************************/
231 switch( ri.riDescription.bdColorEncoding )
232 {
233 case BMcoBLACKWHITE:
234 case BMcoWHITEBLACK:
235 bmAverageMono8Image( &(ri.riDescription), bdIn,
236 ri.riBytes, riIn->riBytes, xpixels, ypixels );
237 break;
238
239 case BMcoRGB:
240 bmAverageRgb24Image( &(ri.riDescription), bdIn,
241 ri.riBytes, riIn->riBytes, xpixels, ypixels );
242 break;
243
244 case BMcoRGB8PALETTE:
245 default:
246 LDEB(ri.riDescription.bdColorEncoding);
247 return -1;
248 }
249
250 /* steal */
251 *riOut= ri; bmInitRasterImage( &ri );
252
253 ready:
254
255 bmCleanRasterImage( &ri );
256
257 return rval;
258 }
259
260