source: trunk/JPGPROC/source/gbmsrc/gbmscale.c@ 2

Last change on this file since 2 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 3.8 KB
Line 
1/*
2
3gbmscale.c - Scale bitmap to new size
4
5*/
6
7/*...sincludes:0:*/
8#include <stdio.h>
9#include <stddef.h>
10#include <stdlib.h>
11#include <string.h>
12#include "gbm.h"
13
14/*...vgbm\46\h:0:*/
15/*...e*/
16
17/*...sgbm_simple_scale \45\ point sampled:0:*/
18/*...ssimple_scale_1:0:*/
19static void simple_scale_1(
20 const byte *s,
21 byte *d, int dw,
22 const int xs[]
23 )
24 {
25 int sx = 0;
26 byte bit, value;
27
28 for ( ; dw >= 8; dw -= 8 )
29 {
30 for ( value = 0, bit = 0x80; bit > 0; bit >>= 1 )
31 {
32 if ( s[(unsigned)sx>>3]&(0x80U>>((unsigned)sx&7U)) )
33 value |= bit;
34 sx += *xs++;
35 }
36 *d++ = value;
37 }
38
39 if ( dw > 0 )
40 {
41 for ( value = 0, bit = 0x80; dw-- > 0; bit >>= 1 )
42 {
43 if ( s[(unsigned)sx>>3]&(0x80U>>((unsigned)sx&7U)) )
44 value |= bit;
45 sx += *xs++;
46 }
47 *d = value;
48 }
49 }
50/*...e*/
51/*...ssimple_scale_4:0:*/
52static void simple_scale_4(
53 const byte *s,
54 byte *d, int dw,
55 const int xs[]
56 )
57 {
58 int sx = 0;
59 for ( ;; )
60 {
61 if ( dw-- == 0 ) return;
62 if ( sx&1 ) *d = (s[(unsigned)sx>>1] << 4 );
63 else *d = (s[(unsigned)sx>>1]&0xf0U);
64 sx += *xs++;
65
66 if ( dw-- == 0 ) return;
67 if ( sx&1 ) *d++ |= (s[(unsigned)sx>>1]&0x0fU);
68 else *d++ |= (s[(unsigned)sx>>1] >> 4);
69 sx += *xs++;
70 }
71 }
72/*...e*/
73/*...ssimple_scale_8:0:*/
74static void simple_scale_8(
75 const byte *s,
76 byte *d, int dw,
77 const int xs[]
78 )
79 {
80 while ( dw-- > 0 )
81 {
82 *d++ = *s;
83 s += *xs++;
84 }
85 }
86/*...e*/
87/*...ssimple_scale_24:0:*/
88static void simple_scale_24(
89 const byte *s,
90 byte *d, int dw,
91 const int xs[]
92 )
93 {
94 while ( dw-- > 0 )
95 {
96 *d++ = s[0];
97 *d++ = s[1];
98 *d++ = s[2];
99 s += ( 3 * *xs++ );
100 }
101 }
102/*...e*/
103/*...sfast_simple_scale_1:0:*/
104static void fast_simple_scale_1(
105 const byte *s,
106 byte *d, int dw,
107 const int xs[]
108 )
109 {
110 xs=xs; /* Suppress warnings */
111 memcpy(d, s, (unsigned)(dw+7) >> 3);
112 }
113/*...e*/
114/*...sfast_simple_scale_4:0:*/
115static void fast_simple_scale_4(
116 const byte *s,
117 byte *d, int dw,
118 const int xs[]
119 )
120 {
121 xs=xs; /* Suppress warnings */
122 memcpy(d, s, (unsigned) (dw+1)>>1);
123 }
124/*...e*/
125/*...sfast_simple_scale_8:0:*/
126static void fast_simple_scale_8(
127 const byte *s,
128 byte *d, int dw,
129 const int xs[]
130 )
131 {
132 xs=xs; /* Suppress warnings */
133 memcpy(d, s, dw);
134 }
135/*...e*/
136/*...sfast_simple_scale_24:0:*/
137static void fast_simple_scale_24(
138 const byte *s,
139 byte *d, int dw,
140 const int xs[]
141 )
142 {
143 xs=xs; /* Suppress warnings */
144 memcpy(d, s, dw*3);
145 }
146/*...e*/
147
148GBM_ERR gbm_simple_scale(
149 const byte *s, int sw, int sh,
150 byte *d, int dw, int dh,
151 int bpp
152 )
153 {
154 int sst = ( (sw * bpp + 31) / 32 ) * 4;
155 int dst = ( (dw * bpp + 31) / 32 ) * 4;
156 int *xs, *ys, i;
157 void (*scaler)(const byte *s, byte *d, int dw, const int xs[]);
158
159 /* Allocate memory for step arrays */
160
161 if ( (xs = malloc((size_t) ((dw+1+dh+1)*sizeof(int)))) == NULL )
162 return GBM_ERR_MEM;
163 ys = xs + (dw+1);
164
165 /* Make mapping to 0..dx from 0..sx (and same for y) */
166
167 for ( i = 0; i <= dw; i++ )
168 xs[i] = (i * sw) / dw;
169
170 for ( i = 0; i <= dh; i++ )
171 ys[i] = (i * sh) / dh;
172
173 /* Compute step coefficients */
174
175 for ( i = 0; i < dw; i++ )
176 xs[i] = xs[i+1] - xs[i];
177
178 for ( i = 0; i < dh; i++ )
179 ys[i] = ys[i+1] - ys[i];
180
181 /* Pick a scaling routine. Special optimisation to prevent
182 excessive work scaling horizontally if widths are the same.
183 Effectively reduces this code to a memcpy. */
184
185 if ( dw == sw )
186 switch ( bpp )
187 {
188 case 1 : scaler = fast_simple_scale_1 ; break;
189 case 4 : scaler = fast_simple_scale_4 ; break;
190 case 8 : scaler = fast_simple_scale_8 ; break;
191 case 24: scaler = fast_simple_scale_24; break;
192 }
193 else
194 switch ( bpp )
195 {
196 case 1 : scaler = simple_scale_1 ; break;
197 case 4 : scaler = simple_scale_4 ; break;
198 case 8 : scaler = simple_scale_8 ; break;
199 case 24: scaler = simple_scale_24; break;
200 }
201
202 /* Now do guts of scaling */
203
204 while ( dh-- > 0 )
205 {
206 (*scaler)(s, d, dw, xs);
207 d += dst;
208 s += (sst * *ys++);
209 }
210
211 free(xs);
212 return GBM_ERR_OK;
213 }
214/*...e*/
Note: See TracBrowser for help on using the repository browser.