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