source: trunk/JPGPROC/source/gbmsrc/gbmrect.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: 5.5 KB
Line 
1/*
2
3gbmrect.c - Subrectangle Transfer
4
5*/
6
7/*...sincludes:0:*/
8#include <stdio.h>
9#include <ctype.h>
10#include <string.h>
11#include <stddef.h>
12#include <stdlib.h>
13#include "gbm.h"
14
15/*...vgbm\46\h:0:*/
16/*...e*/
17
18/*...sgbm_subrectangle:0:*/
19/*...smiddle_4:0:*/
20static void middle_4(byte *dst, const byte *src, int x, int w)
21 {
22 if ( x & 1 )
23 {
24 src += (x / 2);
25 for ( ; w >= 2; w -= 2 )
26 {
27 *dst = (byte) (*src++ << 4);
28 *dst++ |= (byte) (*src >> 4);
29 }
30 if ( w )
31 *dst = (byte) (*src << 4);
32 }
33 else
34 memcpy(dst, src + x / 2, (w + 1) / 2);
35 }
36/*...e*/
37/*...smiddle_1:0:*/
38static void middle_1(byte *dst, const byte *src, int x, int w)
39 {
40 int last = (x & 7);
41
42 src += (x/8);
43 if ( last )
44 {
45 for ( ; w >= 8; w -= 8 )
46 {
47 *dst = (byte) (*src++ << last);
48 *dst++ |= (byte) (*src >> (8U - last));
49 }
50 if ( w )
51 {
52 *dst = (byte) (*src++ << last);
53 w -= (8U-last);
54 if ( w )
55 *dst |= (byte) (*src >> (8U - last));
56 }
57 }
58 else
59 memcpy(dst, src, (w + 7) / 8);
60 }
61/*...e*/
62
63void gbm_subrectangle(
64 const GBM *gbm,
65 int x, int y, int w, int h,
66 const byte *data_src, byte *data_dst
67 )
68 {
69 int i;
70 int stride_src = ( ((gbm->w * gbm->bpp + 31)/32) * 4 );
71 int stride_dst = ( (( w * gbm->bpp + 31)/32) * 4 );
72
73 data_src += stride_src * y;
74
75 switch ( gbm->bpp )
76 {
77 case 24:
78 for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
79 memcpy(data_dst, data_src + x * 3, w * 3);
80 break;
81 case 8:
82 for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
83 memcpy(data_dst, data_src + x, w);
84 break;
85 case 4:
86 for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
87 middle_4(data_dst, data_src, x, w);
88 break;
89 case 1:
90 for ( i = 0; i < h; i++, data_src += stride_src, data_dst += stride_dst )
91 middle_1(data_dst, data_src, x, w);
92 break;
93 }
94 }
95/*...e*/
96/*...sgbm_blit:0:*/
97/*...sblit_1:0:*/
98static void blit_1(
99 const byte *s, int sts, int sx,
100 byte *d, int dts, int dx,
101 int w, int h
102 )
103 {
104 s += (sx>>3); sx &= 7;
105 d += (dx>>3); dx &= 7;
106
107 if ( sx == dx )
108/*...saligned transfer:16:*/
109{
110int left, right, middle = w;
111byte left_mask, right_mask;
112
113/* If starting mid-byte, then remember this */
114if ( (sx&7)!=0 && middle > 0 )
115 { left = 8-(sx&7); middle -= left; }
116else
117 left = 0;
118/* If ending mid-byte, then remember this */
119if ( ((sx+w)&7)!=0 && middle > 0 )
120 { right = ((sx+w)&7); middle -= right; }
121else
122 right = 0;
123/* Remainder will be a multiple of 8, divide by 8 to give bytes */
124middle >>= 3;
125
126left_mask = (byte) (0xffU<<left );
127right_mask = (byte) (0xffU>>right);
128
129for ( ; h-- > 0; s += sts, d += dts )
130 {
131 const byte *sp = s;
132 byte *dp = d;
133 if ( left > 0 )
134 { *dp = ( (*dp&left_mask) | (*sp&~left_mask) ); dp++; sp++; }
135 memcpy(dp, sp, middle); dp += middle; sp += middle;
136 if ( right )
137 *dp = ( (*dp&right_mask) | (*sp&~right_mask) );
138 }
139}
140/*...e*/
141 else
142/*...smisaligned transfer:16:*/
143/* This will be very inefficient, but will work */
144
145for ( ; h-- > 0; s += sts, d += dts )
146 {
147 int x, sxl, dxl;
148 for ( x = 0, sxl = sx, dxl = dx; x < w; x++, sxl++, dxl++ )
149 if ( s[(unsigned)sxl>>3] & (0x80U>>((unsigned)sxl&7U)) )
150 d[(unsigned)dxl>>3] |= (0x80U>>((unsigned)dxl&7U));
151 else
152 d[(unsigned)dxl>>3] &= ~(0x80U>>((unsigned)dxl&7U));
153 }
154/*...e*/
155 }
156/*...e*/
157/*...sblit_4:0:*/
158static void blit_4(
159 const byte *s, int sts, int sx,
160 byte *d, int dts, int dx,
161 int w, int h
162 )
163 {
164 s += ((unsigned)sx>>1); sx &= 1;
165 d += ((unsigned)dx>>1); dx &= 1;
166
167 if ( sx == dx )
168/*...saligned transfer:16:*/
169{
170BOOLEAN lnibble, rnibble;
171int middle = w;
172
173/* If starting mid-byte, then remember this */
174if ( (sx&1)!=0 && middle > 0 )
175 { lnibble = TRUE; middle--; }
176else
177 lnibble = FALSE;
178/* If ending mid-byte, then remember this */
179if ( ((sx+w)&1)!=0 && middle > 0 )
180 { rnibble = TRUE; middle--; }
181else
182 rnibble = FALSE;
183/* Remainder will be a multiple of 2, divide by 2 to give bytes */
184middle >>= 1;
185
186for ( ; h-- > 0; s += sts, d += dts )
187 {
188 const byte *sp = s;
189 byte *dp = d;
190 if ( lnibble )
191 { *dp = ( (*dp&0xf0) | (*sp&0x0f) ); dp++; sp++; }
192 memcpy(dp, sp, middle); dp += middle; sp += middle;
193 if ( rnibble )
194 *dp = ( (*dp&0x0f) | (*sp&0xf0) );
195 }
196}
197/*...e*/
198 else
199/*...smisaligned transfer:16:*/
200/* This will be quite inefficient, but will work */
201
202for ( ; h-- > 0; s += sts, d += dts )
203 {
204 int x, sxl, dxl;
205 for ( x = 0, sxl = sx, dxl = dx; x < w; x++, sxl++, dxl++ )
206 if ( x&1 )
207 d[(unsigned)dxl>>1] = ( (d[(unsigned)dxl>>1]&0xf0U) | s[(unsigned)sxl>>1]>>4 );
208 else
209 d[(unsigned)dxl>>1] = ( (d[(unsigned)dxl>>1]&0x0fU) | s[(unsigned)sxl>>1]<<4 );
210 }
211/*...e*/
212 }
213/*...e*/
214/*...sblit_8:0:*/
215static void blit_8(
216 const byte *s, int sts, int sx,
217 byte *d, int dts, int dx,
218 int w, int h
219 )
220 {
221 s += sx;
222 d += dx;
223 for ( ; h-- > 0; s += sts, d += dts )
224 memcpy(d, s, w);
225 }
226/*...e*/
227/*...sblit_24:0:*/
228static void blit_24(
229 const byte *s, int sts, int sx,
230 byte *d, int dts, int dx,
231 int w, int h
232 )
233 {
234 s += (sx*3);
235 d += (dx*3);
236 for ( ; h-- > 0; s += sts, d += dts )
237 memcpy(d, s, w*3);
238 }
239/*...e*/
240
241void gbm_blit(
242 const byte *s, int sw, int sx, int sy,
243 byte *d, int dw, int dx, int dy,
244 int w, int h,
245 int bpp
246 )
247 {
248 int sts = ((sw * bpp + 31) / 32) * 4;
249 int dts = ((dw * bpp + 31) / 32) * 4;
250
251 if ( w == 0 || h == 0 )
252 return;
253
254 s += sts * sy;
255 d += dts * dy;
256 switch ( bpp )
257 {
258 case 1: blit_1 (s,sts,sx, d,dts,dx, w,h); break;
259 case 4: blit_4 (s,sts,sx, d,dts,dx, w,h); break;
260 case 8: blit_8 (s,sts,sx, d,dts,dx, w,h); break;
261 case 24: blit_24(s,sts,sx, d,dts,dx, w,h); break;
262 }
263 }
264/*...e*/
Note: See TracBrowser for help on using the repository browser.