build infplane for all targets .. only use the asm where supported.
[AROS-Contrib.git] / Demo / PowerZoom / powerzoom.c
blob18e245774c9ccf5588da0111f621345678943634
1 #include <intuition/intuition.h>
2 #include <graphics/gfx.h>
3 #include <cybergraphx/cybergraphics.h>
4 #include <datatypes/pictureclass.h>
5 #include <datatypes/datatypesclass.h>
6 #include <proto/alib.h>
7 #include <proto/exec.h>
8 #include <proto/dos.h>
9 #include <proto/graphics.h>
10 #include <proto/cybergraphics.h>
11 #include <proto/intuition.h>
12 #include <proto/datatypes.h>
14 #include <math.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
19 #define SCREENWIDTH imagewidth
20 #define SCREENHEIGHT imageheight
21 #define SCREENCY (SCREENHEIGHT / 2)
23 /***********************************************************************************/
25 struct IntuitionBase *IntuitionBase;
26 struct GfxBase *GfxBase;
27 struct Library *CyberGfxBase;
28 struct Library *DataTypesBase;
29 struct Screen *scr;
30 struct Window *win;
31 struct RastPort *rp;
32 Object *dto;
33 UBYTE *imagebuffer, *imagebuffer2;
34 LONG imagewidth, imageheight, zoomwidth, zoomheight;
35 BOOL maxspeed, hiquality = TRUE;
36 UBYTE filename[1024];
37 ULONG cgfx_coltab[256];
38 WORD winx = -1, winy = -1;
40 /***********************************************************************************/
42 void cleanup(char *msg)
44 if (msg)
46 printf("powerzoom: %s\n",msg);
49 if (win) CloseWindow(win);
51 if (imagebuffer) FreeVec(imagebuffer);
52 if (dto) DisposeDTObject(dto);
54 if (scr) UnlockPubScreen(0, scr);
56 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
57 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
58 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
60 exit(0);
63 /***********************************************************************************/
65 #define ARG_TEMPLATE "IMAGEFILE,WINPOSX=X/N/K,WINPOSY=Y/N/K,MAXSPEED/S"
66 #define ARG_FILE 0
67 #define ARG_X 1
68 #define ARG_Y 2
69 #define ARG_MAXSPEED 3
70 #define NUM_ARGS 4
72 static IPTR args[NUM_ARGS];
74 static void getarguments(void)
76 struct RDArgs *myargs;
78 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
80 if (args[ARG_FILE])
82 strncpy(filename, (char *)args[ARG_FILE], sizeof(filename));
84 else
86 strncpy(filename, "SYS:Images/AROS.png", sizeof(filename));
88 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
89 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
90 if (args[ARG_MAXSPEED]) maxspeed = TRUE;
92 FreeArgs(myargs);
94 else
96 PrintFault(IoErr(), "PowerZoom");
97 cleanup(0);
102 /***********************************************************************************/
104 void openlibs(void)
106 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
108 cleanup("Can't open intuition.library V39!");
111 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
113 cleanup("Can't open graphics.library V39!");
116 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
118 cleanup("Can't open cybergraphics.library!");
121 if (!(DataTypesBase = OpenLibrary("datatypes.library",0)))
123 cleanup("Can't open datatypes.library!");
127 /***********************************************************************************/
129 void getvisual(void)
131 scr = LockPubScreen(NULL);
132 if (!scr) cleanup("Can't lock public screen!");
134 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) < 15)
136 cleanup("Need hicolor/truecolor screen!");
140 /***********************************************************************************/
142 void openpic(void)
144 dto = NewDTObject(filename,
145 DTA_GroupID, GID_PICTURE,
146 PDTA_Screen, (IPTR)scr,
147 PDTA_Remap, TRUE,
148 PDTA_DestMode, PMODE_V43,
149 PDTA_UseFriendBitMap, TRUE,
150 TAG_DONE);
152 if (!dto) cleanup("Can't open picture!");
155 /***********************************************************************************/
157 void readpic(void)
159 struct BitMapHeader *bmhd = NULL;
160 struct BitMap *dtobm = NULL;
161 struct RastPort temprp;
163 DoMethod(dto, DTM_PROCLAYOUT, NULL, 1);
165 GetDTAttrs(dto, PDTA_BitMapHeader, (IPTR)&bmhd, PDTA_DestBitMap, (IPTR)&dtobm, TAG_DONE);
166 if (!bmhd || !dtobm)
168 cleanup("Error reading datatype image!");
171 imagewidth = bmhd->bmh_Width; imageheight = bmhd->bmh_Height;
173 imagebuffer = AllocVec(imagewidth * imageheight * 4 * 2, MEMF_ANY);
174 if (!imagebuffer)
176 cleanup("Error allocating image buffer!");
178 imagebuffer2 = imagebuffer + imagewidth * imageheight * 4;
180 InitRastPort(&temprp);
181 temprp.BitMap = dtobm;
182 ReadPixelArray(imagebuffer, 0, 0, imagewidth * 4,
183 &temprp, 0, 0, imagewidth, imageheight, RECTFMT_ARGB);
185 DisposeDTObject(dto); dto = NULL;
188 /***********************************************************************************/
190 void makewin(void)
192 if (winx == -1) winx = (scr->Width - SCREENWIDTH - scr->WBorLeft - scr->WBorRight) / 2;
193 if (winy == -1) winy = (scr->Height - SCREENHEIGHT - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
195 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
196 WA_Left , winx,
197 WA_Top , winy,
198 WA_InnerWidth , SCREENWIDTH,
199 WA_InnerHeight , SCREENHEIGHT,
200 WA_AutoAdjust , TRUE,
201 WA_Activate , TRUE,
202 WA_IDCMP , IDCMP_CLOSEWINDOW |
203 IDCMP_RAWKEY | IDCMP_VANILLAKEY,
204 WA_DragBar , TRUE,
205 WA_DepthGadget , TRUE,
206 WA_CloseGadget , TRUE,
207 WA_Title , (IPTR)"PowerZoom: SPACE = switch quality S = switch speed limit",
208 TAG_DONE);
210 if (!win) cleanup("Can't open window");
212 rp = win->RPort;
216 /***********************************************************************************/
218 void uglyzoom(void)
220 LONG x, y, gx, gy, stepx, stepy;
221 ULONG *src;
222 ULONG *dest = (ULONG *)imagebuffer2;
224 stepx = imagewidth * 0x10000 / zoomwidth;
225 stepy = imageheight * 0x10000 / zoomheight;
227 for(y = 0, gy = 0; y < zoomheight; y++, gy += stepy)
229 src = ((ULONG *)imagebuffer) + (gy / 0x10000) * imagewidth;
231 for(x = 0, gx = 0; x < zoomwidth; x++, gx += stepx)
233 *dest++ = src[(gx / 0x10000)];
238 /***********************************************************************************/
240 void nicezoom(void)
242 LONG x, y, gx, gy, stepx, stepy, sx, sy, nx, ny, sample_w, sample_h, sample_size;
243 LONG pix_w, pix_h, pix_size;
244 int iter = 0;
246 ULONG *dest = (ULONG *)imagebuffer2;
248 stepx = imagewidth * 0x10000 / zoomwidth;
249 stepy = imageheight * 0x10000 / zoomheight;
251 for(y = 0, gy = 0; y < zoomheight; y++, gy += stepy)
253 # define PRINT(d) // if (y == 1 && x == 2) d
255 for(x = 0, gx = 0; x < zoomwidth; x++, gx += stepx)
257 ULONG r = 0, g = 0, b = 0;
258 LONG gx2 = gx + stepx;
259 LONG gy2 = gy + stepy;
261 sample_w = gx2 - gx;
262 sample_h = gy2 - gy;
263 sample_size = (sample_w >> 8) * (sample_h >> 8);
264 sample_size += (sample_size >> 8);
266 if (!sample_size)
268 dest++;
269 continue;
272 for(sy = gy; sy < gy2; sy = ny)
274 ny = (sy + 0x10000) & 0xFFFF0000;
275 if (ny > gy2) ny = gy2;
277 for(sx = gx; sx < gx2; sx = nx)
279 ULONG src, pix_r, pix_g, pix_b;
281 nx = (sx + 0x10000) & 0xFFFF0000;
282 if (nx > gx2) nx = gx2;
284 pix_w = nx - sx;
285 pix_h = ny - sy;
286 pix_size = ((pix_w >> 8) * (pix_h >> 8));
287 //pix_size += (pix_size >> 8);
289 PRINT(kprintf("pix_size[%x,%x] %x\n",sx,sy,pix_size));
291 src = ((ULONG *)imagebuffer)[(sy / 0x10000) * imagewidth + sx / 0x10000];
293 #if AROS_BIG_ENDIAN
294 pix_r = (src >> 16) & 0xFF;
295 pix_g = (src >> 8) & 0xFF;
296 pix_b = (src) & 0xFF;
297 #else
298 pix_r = (src >> 8) & 0xFF;
299 pix_g = (src >> 16) & 0xFF;
300 pix_b = (src >> 24) & 0xFF;
301 #endif
303 r += pix_r * pix_size;
304 g += pix_g * pix_size;
305 b += pix_b * pix_size;
307 iter++;
312 r /= sample_size;
313 g /= sample_size;
314 b /= sample_size;
316 #if AROS_BIG_ENDIAN
317 *dest++ = (r << 16) | (g << 8) | b;
318 #else
319 *dest++ = (r << 8) | (g << 16) | (b << 24);
320 #endif
324 //kprintf("iterations: %d\n", iter);
327 /***********************************************************************************/
329 void action(void)
331 static int direction = -1;
333 if (zoomwidth && zoomheight)
335 if (hiquality)
337 nicezoom();
339 else
341 uglyzoom();
344 WritePixelArray(imagebuffer2,
347 zoomwidth * 4,
349 win->BorderLeft,
350 win->BorderTop,
351 (zoomwidth < win->GZZWidth ? zoomwidth : win->GZZWidth),
352 (zoomheight < win->GZZHeight ? zoomheight : win->GZZHeight),
353 RECTFMT_ARGB);
356 #if 1
357 zoomwidth += direction;
358 if ((zoomwidth == imagewidth) || (zoomwidth < 3)) direction = -direction;
359 zoomheight = zoomwidth * imageheight / imagewidth;
360 #else
361 zoomwidth = imagewidth * 2 / 3;
362 zoomheight = imageheight;
363 #endif
368 /***********************************************************************************/
370 void handleall(void)
372 struct IntuiMessage *msg;
373 BOOL quitme = FALSE;
375 zoomwidth = imagewidth;
376 zoomheight = imageheight;
378 while(!quitme)
380 if (!maxspeed) WaitTOF();
381 action();
382 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
384 switch(msg->Class)
386 case IDCMP_CLOSEWINDOW:
387 quitme = TRUE;
388 break;
390 case IDCMP_VANILLAKEY:
391 switch(msg->Code)
393 case 27:
394 quitme = TRUE;
395 break;
397 case ' ':
398 hiquality = !hiquality;
399 break;
401 case 'S':
402 case 's':
403 maxspeed = !maxspeed;
404 break;
406 break;
409 ReplyMsg((struct Message *)msg);
415 /***********************************************************************************/
417 int main(int argc, char *argv[])
419 getarguments();
420 openlibs();
421 getvisual();
422 openpic();
423 readpic();
424 makewin();
425 handleall();
426 cleanup(0);
427 return 0;
430 /***********************************************************************************/