1 #include <stdio.h>
2 #include "inforegion.h"
3 #include "tnz4.h"
4 /*---------------------------------------------------------------------------*/
5
6 #ifndef min
7 #define min(a, b) (((a) < (b)) ? (a) : (b))
8 #endif
9 #ifndef max
10 #define max(a, b) (((a) > (b)) ? (a) : (b))
11 #endif
12
getInfoRegion(INFO_REGION * region,int x1_out,int y1_out,int x2_out,int y2_out,int scale,int width_in,int height_in)13 void getInfoRegion(INFO_REGION *region, int x1_out, int y1_out, int x2_out,
14 int y2_out, int scale, int width_in, int height_in) {
15 /*
16 * I suffissi _in e _out sono relativi alle immagini di
17 * input e output, cioe' all'immagine sorgente (input)
18 * ca cui prendere (leggere) la regione voluta (output).
19 */
20
21 int x1_in, y1_in, x2_in, y2_in;
22
23 #define SWAP(a, b) \
24 { \
25 int tmp; \
26 tmp = a; \
27 a = b; \
28 b = tmp; \
29 }
30
31 /* Scambia le coordinate della regione da leggere se invertite */
32 if (x1_out > x2_out) SWAP(x1_out, x2_out);
33 if (y1_out > y2_out) SWAP(y1_out, y2_out);
34
35 #ifdef DEBUG
36 /* Controllo della consistenza delle coordinate della regione */
37 if (((x2_out - x1_out) < 0) || ((y2_out - y1_out) < 0))
38 printf("warning: bad region coord.\n");
39 #endif
40
41 /* Copia delle coordinate della regione per region globale */
42 region->x1 = x1_out;
43 region->y1 = y1_out;
44 region->x2 = x2_out;
45 region->y2 = y2_out;
46
47 /* Imposta le dimensioni dell'immagine in output */
48 if (scale <= 0) {
49 printf("error: scale value negative or zero\n");
50 return;
51 } else {
52 region->xsize = ((x2_out - x1_out + 1) - 1) / scale + 1;
53 region->ysize = ((y2_out - y1_out + 1) - 1) / scale + 1;
54 }
55
56 /* Passo sull'asse delle y e delle x */
57 region->step = scale;
58
59 /* Coordinate immagine sorgente */
60 x1_in = 0;
61 y1_in = 0;
62 x2_in = width_in - 1;
63 y2_in = height_in - 1;
64
65 /* Dimensioni immagine sorgente */
66 region->lx_in = width_in;
67 region->ly_in = height_in;
68
69 /* Numero di righe e colonne dell'immagine sorgente da scandire */
70 region->scanNcol = region->xsize;
71 region->scanNrow = region->ysize;
72
73 /* Coordinate all'interno dell'immagine sorgente, da cui deve
74 * partire la scansione.
75 */
76 region->startScanRow = y1_out;
77 region->startScanCol = x1_out - x1_in;
78
79 /*
80 * Questi offset sono relativi al buffer di uscita, nel caso
81 * in cui una parte della regione sfora rispetto all'immagine
82 * sorgente.
83 */
84 region->x_offset = 0;
85 region->y_offset = 0;
86
87 /* La regione sfora sulla destra e sulla sinistra */
88 if (x2_out > x2_in && x1_out < x1_in) {
89 region->scanNcol = width_in / scale;
90 region->x_offset = (x1_in - x1_out) / scale;
91 region->startScanCol = 0;
92 } else {
93 /* La regione sfora solo sulla destra */
94 if (x2_out > x2_in) {
95 region->scanNcol = (x2_in - x1_out) / scale + 1;
96 region->x_offset = 0;
97 } else
98 /* La regione sfora solo sulla sinistra */
99 if (x1_out < x1_in) {
100 region->x_offset = (x1_in - x1_out) / scale;
101 region->scanNcol = (x2_out - x1_in) / scale + 1;
102 region->startScanCol = 0;
103 }
104 }
105
106 /* La regione sfora in alto e in basso */
107 if (y2_out > y2_in && y1_out < y1_in) {
108 region->scanNrow = height_in / scale;
109 region->y_offset = (y1_in - y1_out) / scale;
110 region->startScanRow = 0;
111 } else {
112 /* La regione sfora solo in alto */
113 if (y2_out > y2_in) {
114 region->scanNrow = (y2_in - y1_out) / scale + 1;
115 region->y_offset = 0;
116 } else
117 /* La regione sfora solo in basso */
118 if (y1_out < y1_in) {
119 region->scanNrow = (y2_out - y1_in) / scale + 1;
120 region->y_offset = (y1_in - y1_out) / scale;
121 region->startScanRow = 0;
122 }
123 }
124 }
125
126 /*---------------------------------------------------------------------------*/
127
get_info_region(EXT_INFO_REGION * region,int x1_out,int y1_out,int x2_out,int y2_out,int scale,int width_in,int height_in,int orientation)128 int get_info_region(EXT_INFO_REGION *region, int x1_out, int y1_out, int x2_out,
129 int y2_out, int scale, int width_in, int height_in,
130 int orientation) {
131 /*
132 * I suffissi _in e _out sono relativi alle immagini di
133 * input e output, cioe' all'immagine sorgente (input)
134 * ca cui prendere (leggere) la regione voluta (output).
135 */
136
137 int x1_in, y1_in, x2_in, y2_in;
138 int appo, appoNcol, appoNrow;
139
140 #define SWAP(a, b) \
141 { \
142 int tmp; \
143 tmp = a; \
144 a = b; \
145 b = tmp; \
146 }
147
148 /* Scambia le coordinate della regione da leggere se invertite */
149 if (x1_out > x2_out) SWAP(x1_out, x2_out);
150 if (y1_out > y2_out) SWAP(y1_out, y2_out);
151
152 /* Controllo della consistenza delle coordinate della regione */
153 if (((x2_out - x1_out) < 1) || ((y2_out - y1_out) < 1)) {
154 printf("error: bad image read region coordinates\n");
155 return FALSE;
156 }
157
158 /* Copia delle coordinate della regione per region globale */
159 region->x1 = x1_out;
160 region->y1 = y1_out;
161 region->x2 = x2_out;
162 region->y2 = y2_out;
163
164 /* Imposta le dimensioni dell'immagine in output */
165 if (scale <= 0) {
166 printf("error: scale value negative or zero\n");
167 return FALSE;
168 } else {
169 region->xsize = (x2_out - x1_out) / scale + 1;
170 region->ysize = (y2_out - y1_out) / scale + 1;
171 }
172
173 /* Passo sull'asse delle y e delle x */
174 region->step = scale;
175
176 /* Coordinate immagine sorgente */
177 x1_in = 0;
178 y1_in = 0;
179 x2_in = width_in - 1;
180 y2_in = height_in - 1;
181
182 /* Dimensioni immagine sorgente */
183 region->lx_in = width_in;
184 region->ly_in = height_in;
185
186 /* Numero di righe e colonne dell'immagine sorgente da scandire */
187 region->scanNcol = region->xsize;
188 region->scanNrow = region->ysize;
189
190 /* Coordinate all'interno dell'immagine sorgente, da cui deve
191 * partire la scansione.
192 */
193 region->startScanRow = y1_out;
194 region->startScanCol = x1_out;
195
196 /*
197 * Questi offset sono relativi al buffer di uscita, nel caso
198 * in cui una parte della regione sfora rispetto all'immagine
199 * sorgente.
200 */
201 region->x_offset = 0;
202 region->y_offset = 0;
203
204 /* La regione sfora sulla destra e sulla sinistra */
205 if (x2_out > x2_in && x1_out < x1_in) {
206 region->scanNcol = (width_in - 1) / scale /* +1 */;
207 region->x_offset = (x1_in - x1_out + scale - 1) / scale;
208 region->startScanCol = 0;
209 } else {
210 /* La regione sfora solo sulla destra */
211 if (x2_out > x2_in) {
212 region->scanNcol = (x2_in - x1_out) / scale /* +1 */;
213 region->x_offset = 0;
214 } else
215 /* La regione sfora solo sulla sinistra */
216 if (x1_out < x1_in) {
217 region->scanNcol = (x2_out - x1_in) / scale /* +1 */;
218 region->x_offset = (x1_in - x1_out + scale - 1) / scale;
219 region->startScanCol = 0;
220 }
221 }
222
223 /* La regione sfora in alto e in basso */
224 if (y2_out > y2_in && y1_out < y1_in) {
225 region->scanNrow = (height_in - 1) / scale /* +1 */;
226 region->y_offset = (y1_in - y1_out + scale - 1) / scale;
227 region->startScanRow = 0;
228 } else {
229 /* La regione sfora solo in alto */
230 if (y2_out > y2_in) {
231 region->scanNrow = (y2_in - y1_out) / scale /* +1 */;
232 region->y_offset = 0;
233 } else
234 /* La regione sfora solo in basso */
235 if (y1_out < y1_in) {
236 region->scanNrow = (y2_out - y1_in) / scale /* +1 */;
237 region->y_offset = (y1_in - y1_out + scale - 1) / scale;
238 region->startScanRow = 0;
239 }
240 }
241
242 appoNcol = min((region->scanNcol * scale), width_in);
243 appoNrow = min((region->scanNrow * scale), height_in);
244
245 switch (orientation) {
246 case TNZ_TOPLEFT:
247 region->buf_inc = 1;
248 region->y_offset += region->scanNrow - 1;
249 region->verso_x = 0;
250 region->verso_y = -1;
251 region->sxpix = region->startScanCol;
252 region->sypix = height_in - region->startScanRow - appoNrow;
253 region->sypix = max(0, region->sypix);
254 break;
255 case TNZ_TOPRIGHT:
256 region->buf_inc = -1;
257 region->y_offset += region->scanNrow - 1;
258 region->x_offset += region->scanNcol - 1;
259 region->verso_x = 0;
260 region->verso_y = -1;
261 region->sxpix = width_in - region->startScanCol - appoNcol;
262 region->sypix = height_in - region->startScanRow - appoNrow;
263 region->sxpix = max(0, region->sxpix);
264 region->sypix = max(0, region->sypix);
265 break;
266 case TNZ_BOTRIGHT:
267 region->buf_inc = -1;
268 region->x_offset += region->scanNcol - 1;
269 region->verso_x = 0;
270 region->verso_y = 1;
271 region->sxpix = width_in - region->startScanCol - appoNcol;
272 region->sypix = region->startScanRow;
273 break;
274 case TNZ_BOTLEFT:
275 region->buf_inc = 1;
276 region->verso_x = 0;
277 region->verso_y = 1;
278 region->sxpix = region->startScanCol;
279 region->sypix = region->startScanRow;
280 break;
281 case TNZ_LEFTOP:
282 region->buf_inc = -region->xsize;
283 region->y_offset += region->scanNrow - 1;
284 region->verso_x = 1;
285 region->verso_y = 0;
286 region->sxpix = height_in - region->startScanRow - appoNrow;
287 region->sypix = region->startScanCol;
288 break;
289 case TNZ_RIGHTOP:
290 region->buf_inc = -region->xsize;
291 region->y_offset += region->scanNrow - 1;
292 region->x_offset += region->scanNcol - 1;
293 region->verso_x = -1;
294 region->verso_y = 0;
295 if ((region->sxpix = height_in - region->startScanRow - appoNrow) < 0)
296 region->sxpix = 0;
297 if ((region->sypix = width_in - region->startScanCol - appoNcol) < 0)
298 region->sypix = 0;
299 break;
300 case TNZ_RIGHTBOT:
301 region->buf_inc = region->xsize;
302 region->x_offset += region->scanNcol - 1;
303 region->verso_x = -1;
304 region->verso_y = 0;
305 region->sxpix = region->startScanRow;
306 region->sypix = width_in - region->startScanCol - appoNcol;
307 break;
308 case TNZ_LEFTBOT:
309 region->buf_inc = region->xsize;
310 region->verso_x = 1;
311 region->verso_y = 0;
312 region->sxpix = region->startScanRow;
313 region->sypix = region->startScanCol;
314 break;
315 default:
316 printf("error: bad orientation type\n");
317 return FALSE;
318 }
319 /* Se le righe sono verticali, allora ... */
320 if (orientation > 4) {
321 appo = region->lx_in;
322 region->lx_in = region->ly_in;
323 region->ly_in = appo;
324 appo = region->scanNcol;
325 region->scanNcol = region->scanNrow;
326 region->scanNrow = appo;
327 }
328 return TRUE;
329 }
330
331 /*-------------------------------------------------------------------------*/
332
print_info_region(EXT_INFO_REGION * region)333 void print_info_region(EXT_INFO_REGION *region) {
334 if (!region) return;
335
336 printf("IMAGE INPUT:\n");
337 printf(" size (lx_in, ly_in)........ (%d,%d)\n", region->lx_in,
338 region->ly_in);
339 printf(" start offset (sScanCol, sScanRow).. (%d,%d)\n",
340 region->startScanCol, region->startScanRow);
341 printf(" region size (scanNcol, scanNrow).. (%d,%d)\n",
342 region->scanNcol, region->scanNrow);
343 printf(" bottom-left (sxpix, sypix)........ (%d,%d)\n", region->sxpix,
344 region->sypix);
345 printf(" scale (step)................ ( %d)\n", region->step);
346
347 printf("IMAGE OUTPUT:\n");
348 printf(" size (xsize, ysize)........ (%d,%d)\n", region->xsize,
349 region->ysize);
350 printf(" start offset (x_offset, y_offset).. (%d,%d)\n",
351 region->x_offset, region->y_offset);
352 printf(" verso (verso_x, verso_y).... (%d,%d)\n", region->verso_x,
353 region->verso_y);
354 printf(" buffer increment (buf_inc)............. ( %d)\n",
355 region->buf_inc);
356 }
357