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