Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
getami.c
Go to the documentation of this file.
1 /*
2  * getami.c - display a Utah RLE picture on a Commodore Amiga
3  *
4  * Authors: Eleftherios Koutsofios (ek@ulysses.att.com)
5  * Kriton Kyrimis (kyrimis%theseas@csi.forth.gr)
6  */
7 
8 #include <stdio.h>
9 #include <intuition/intuition.h>
10 #include <libraries/dos.h>
11 #include <exec/types.h>
12 #include <exec/memory.h>
13 #include <graphics/gfxbase.h>
14 #include <graphics/view.h>
15 #ifndef NOIFFLIB
16 #include <iff.h>
17 #endif
18 #include <rle.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #if !defined(MCH_AMIGA) && !defined(LATTICE)
22 #include <signal.h>
23 #endif
24 #ifdef LATTICE
25 #include <proto/intuition.h>
26 #include <proto/graphics.h>
27 #include <proto/dos.h>
28 #include <proto/exec.h>
29 #ifndef NOIFFLIB
30 #include <iffpragmas.h>
31 #endif
32 #endif
33 
34 #define MIN(x, y) ((x) < (y) ? (x) : (y))
35 #define ABS(x) ((x) >= 0 ? (x) : -(x))
36 #define MAX(x,y) ((x) > (y) ? (x) : (y))
37 #define index(r, g, b) ((((r) >> 4) << 8) | (((g) >> 4) << 4) | ((b) >> 4))
38 #define rdist(a, b)
39  ((ABS (((cusage[a].i >> 8) & 0xf) - ((cusage[b].i >> 8) & 0xf))) * 30)
40 #define gdist(a, b)
41  ((ABS (((cusage[a].i >> 4) & 0xf) - ((cusage[b].i >> 4) & 0xf))) * 59)
42 #define bdist(a, b)
43  ((ABS ((cusage[a].i & 0xf) - (cusage[b].i & 0xf))) * 11)
44 #define mapx(x) (x + offsetx)
45 #define mapy(y) (sh - (y) - 1 - offsety)
46 #define fmapy(y) (y + offsety)
47 #define inside(x, y) ((x) >= 0 && (y) >= 0 && (x) < sw && (y) < sh)
48 #define EXACT(x) (x)
49 #define RED(x) ((2 << 4) | x)
50 #define GREEN(x) ((3 << 4) | x)
51 #define BLUE(x) ((1 << 4) | x)
52 #define SQ(x) (SQtmp = (x), SQtmp * SQtmp)
53 
54 #define MAX_X 362
55 #define MAX_Y_NTSC 241
56 #define MAX_Y_PAL 283
57 
58 #define BASENAME(x) (strrchr((x),'/') ? strrchr((x),'/')+1 :
59  (strrchr((x),':') ? strrchr((x),':')+1 : (x)))
60 
61 struct GfxBase *GfxBase = NULL;
62 struct IntuitionBase *IntuitionBase = NULL;
63 #ifndef NOIFFLIB
64 struct Library *IFFBase = NULL;
65 #endif
66 
67 static struct NewScreen screen = {
68  0, 0, 0, 0, 6, 1, 0, 0, CUSTOMSCREEN, NULL, "GetAmi", NULL, NULL
69 };
70 
71 static struct Image img = {
72  0, 0, 10, 10, 0, NULL, 0, 0, NULL
73 };
74 
75 static struct Gadget CloseGadget = {
76  NULL, 0, 0, 10, 10, GADGHCOMP | GADGIMAGE, RELVERIFY, BOOLGADGET, (APTR)&img,
77  NULL, NULL, 0, NULL, 1, NULL
78 };
79 
80 static struct NewWindow window = {
81  0, 0, 0, 0, 1, 0, GADGETUP | MENUPICK | MENUVERIFY | REQSET | REQCLEAR,
82  SMART_REFRESH | BACKDROP | BORDERLESS,
83  &CloseGadget, NULL, NULL, NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN
84 };
85 
86 static struct cuse {
87  int i, j;
88 } cusage[4096];
89 
90 static struct Window *w1 = NULL, *w2 = NULL, *w3 = NULL;
91 static struct RastPort *rp1 = NULL, *rp2 = NULL, *rp3 = NULL;
92 static struct Screen *s1 = NULL;
93 static struct Screen *s2 = NULL;
94 static struct Screen *s3 = NULL;
95 static struct ViewPort *vp1 = NULL, *vp2 = NULL, *vp3 = NULL;
96 static rle_pixel *sl[3];
97 static rle_pixel **cmap;
98 static unsigned int R[32], G[32], B[32];
99 static char *tfile, *infile = NULL;
100 static FILE *ifd = NULL, *tfd = NULL;
101 static int width, height, depth, nused, sw, sh, sd, isham;
102 #if 0
103 static int nleft;
104 #endif
105 static int offsetx, offsety;
106 static int bw=0, threescreens=0, havereq=0, havemenu=0, flip=0;
107 static int forceham=0;
108 
109 static USHORT *Ptr = NULL;
110 
111 static USHORT RenderPtr[] = {
112  0x0000, 0x0000,
113  0x7800, 0x3800,
114  0x7000, 0x9000,
115  0x7800, 0x8800,
116  0x5C00, 0xA400,
117  0x0E00, 0x1200,
118  0x0700, 0x0900,
119  0xC300, 0xC400,
120  0xADD1, 0xADD1,
121  0xA955, 0xA955,
122  0xC9FF, 0xC9FF,
123  0x0000, 0x0000,
124  0x0BB8, 0x0BB8,
125  0x0AA8, 0x0AA8,
126  0x0AB8, 0x0AB8,
127  0x0008, 0x0008,
128  0x0038, 0x0038,
129  0x0000, 0x0000
130 };
131 
132 /* SQ temp variable */
133 static int SQtmp;
134 
135 extern struct Window *OpenWindow ();
136 extern struct Screen *OpenScreen ();
137 extern struct Library *OpenLibrary ();
138 extern char *mktemp(char *);
139 extern rle_pixel **buildmap();
140 
141 UBYTE handleIDCMP (void);
142 
143 #define MENUITEMS 3
144 
145 static struct IntuiText txt[] = {
146  { 1, 0, JAM2, 0, 0, NULL, "Save", NULL },
147  { 1, 0, JAM2, 0, 0, NULL, "Save As", NULL },
148  { 1, 0, JAM2, 0, 0, NULL, "Quit", NULL }
149 };
150 
151 static struct MenuItem actions[] = {
152  { &actions[1], 0, 0, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
153  (APTR)&txt[0], NULL, 'S', NULL, MENUNULL
154  },
155  { &actions[2], 0, 10, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
156  (APTR)&txt[1], NULL, 'A', NULL, MENUNULL
157  },
158  { NULL, 0, 20, 68, 8, ITEMTEXT | ITEMENABLED | HIGHBOX | COMMSEQ, 0,
159  (APTR)&txt[2], NULL, 'Q', NULL, MENUNULL
160  }
161 };
162 
163 static struct Menu menu = {
164  NULL, 10, 0, 56, 0, MENUENABLED, "Actions", &actions[0]
165 };
166 
167 static char fnam[80] = {'\0'};
168 static char ufnam[80] = {'\0'};
169 
170 static struct StringInfo fgadinfo = {
171  fnam, ufnam, 0, sizeof(fnam), 0, 0, 0, 0, 0, 0, NULL, 0, NULL
172 };
173 
174 static struct IntuiText ftxt = {
175  0, 1, JAM2, 9, 10, NULL, "File:", NULL
176 };
177 
178 static SHORT fbcoord[] = {1, 1, 146, 1, 146, 26, 1, 26, 1, 1};
179 
180 static struct Border fbord = {
181  0, 0, 0, 1, JAM1, 5, fbcoord, NULL
182 };
183 
184 static struct Gadget fgad = {
185  NULL, 58, 10, 80, 8, GADGHCOMP, ENDGADGET, STRGADGET | REQGADGET,
186  NULL, NULL, NULL, 0, (APTR)&fgadinfo, 0, NULL
187 };
188 
189 #define FREQW 148
190 #define FREQH 28
191 
192 static struct Requester freq = {
193  NULL, 0, 0, FREQW, FREQH, 0, 0, &fgad, &fbord, &ftxt, NULL, 1, NULL,
194  {NULL}, NULL, NULL, {NULL}
195 };
196 
197 void main(int, char **);
198 int compare (struct cuse *, struct cuse *);
199 int find_most_used (void);
200 int display_rle (void);
201 void show_rgb (void);
202 /* Give our signal handler the same name as the default signal handler of
203  the compiler we are using, thus saving a few bytes from the binary */
204 #ifdef MCH_AMIGA
205 void _abort (void);
206 #else
207 int CXBRK(void);
208 #define _abort CXBRK
209 #endif
210 void AdjustScreen(register struct Screen *, int *, int *);
211 void save(void);
212 void FixColors(void);
213 void ResetColors(void);
214 int CalcWidth(int);
215 int CalcHAMWidth(int);
216 int CalcHeight(int, int);
217 
219 
220 #define OptSetAPen1(rp, col) curcol1 = (col); if(curcol1) SetAPen((rp), curcol1)
221 #define OptSetAPen2(rp, col) curcol2 = (col); if(curcol2) SetAPen((rp), curcol2)
222 #define OptSetAPen3(rp, col) curcol3 = (col); if(curcol3) SetAPen((rp), curcol3)
223 
224 #define OptWritePixel1(rp, x, y) if(curcol1) WritePixel((rp), (x), (y))
225 #define OptWritePixel2(rp, x, y) if(curcol2) WritePixel((rp), (x), (y))
226 #define OptWritePixel3(rp, x, y) if(curcol3) WritePixel((rp), (x), (y))
227 
228 void
229 main(int argc, char **argv)
230 {
231  int i, SW=0, SH=0, dump=0, load=0, dx, dy, max_x, max_y;
232  ULONG signalmask, signals;
233  UBYTE done;
234  BYTE pal;
235  FILE *f;
236  struct Preferences prefs;
237  extern char *optarg;
238  extern int optind;
239 
240 /* _abort (#define'd as CXBRK for Lattice) is the default signal handler.
241  No need to call signal, unless we are using some compiler other than
242  Manx/gcc or lattice
243 */
244 #if !defined(MCH_AMIGA) && !defined(LATTICE)
245  (void)signal(SIGINT, (void (*) (int))_abort);
246 #endif
247  while ((i = getopt(argc, argv, "w:h:o:dlb3fH")) != EOF) {
248  switch(i) {
249  case 'w':
250  SW = atoi(optarg);
251  break;
252  case 'h':
253  SH = atoi(optarg);
254  break;
255  case 'o':
256  strcpy(fnam, optarg);
257  break;
258  case 'd':
259  dump = 1;
260  break;
261  case 'l':
262  load = 1;
263  break;
264  case 'b':
265  bw = 1;
266  forceham = 0;
267  threescreens = 0;
268  break;
269  case '3':
270  threescreens = 1;
271  bw = 0;
272  forceham = 0;
273  break;
274  case 'f':
275  flip = 1;
276  break;
277  case 'H':
278  forceham = 1;
279  bw = 0;
280  threescreens = 0;
281  break;
282  case '?':
283  default:
284  fprintf(stderr,
285  "Usage: %s [-dlfb3H] [-w width] [-h height] [-o IFFfile] [file]\n",
286  BASENAME(argv[0]));
287  exit(1);
288  }
289  }
290 
291  if (optind >= argc)
292  ifd = stdin;
293  else{
294  infile = argv[optind];
295  if ((ifd = fopen (infile, "r")) == NULL)
296  fprintf (stderr, "cannot open input file %s\n", infile), _abort ();
297  }
298 
299  if ((tfile = mktemp ("t:rle.XXX")) == NULL)
300  fprintf (stderr, "cannot create a temp name for tfile\n"), _abort ();
301 
302  if ((tfd = fopen (tfile, "w+")) == NULL)
303  fprintf (stderr, "cannot open output file %s\n", tfile), _abort ();
304 
305  if ((GfxBase =
306  (struct GfxBase *) OpenLibrary ("graphics.library", 0L)) == NULL)
307  fprintf (stderr, "Can't open graphics.library\n"), _abort ();
308  pal = (GfxBase->DisplayFlags & PAL) ? 1 : 0;
309 
310  if ((IntuitionBase = (struct IntuitionBase *)
311  OpenLibrary ("intuition.library", 0L)) == NULL)
312  fprintf (stderr, "Can't open intuition.library\n"), _abort ();
313 
314 #ifndef NOIFFLIB
315  if ((IFFBase = OpenLibrary(IFFNAME, IFFVERSION)) == NULL) {
316 #endif
317  actions[0].Flags &= ~ITEMENABLED;
318  actions[1].Flags &= ~ITEMENABLED;
319 #ifndef NOIFFLIB
320  }
321 #endif
322 
323  if (find_most_used () == -1)
324  fprintf (stderr, "error in find_most_used\n"), _abort ();
325 
326  if (load) {
327  f = fopen("cmap", "r");
328  if (!f) {
329  fprintf(stderr, "Can't find cmap file\n");
330  }else{
331  fread((char *)R, sizeof(R), 1, f);
332  fread((char *)G, sizeof(G), 1, f);
333  fread((char *)B, sizeof(B), 1, f);
334  }
335  fclose(f);
336  }
337  if (dump) {
338  f = fopen("cmap", "w");
339  if (!f) {
340  fprintf(stderr, "Can't create cmap file\n");
341  }else{
342  fwrite((char *)R, sizeof(R), 1, f);
343  fwrite((char *)G, sizeof(G), 1, f);
344  fwrite((char *)B, sizeof(B), 1, f);
345  }
346  fclose(f);
347  }
348  fseek (tfd, 0L, 0);
349 
350  if (!forceham && (bw || threescreens || nused <= 32)) {
351  isham = FALSE;
352  sw = CalcWidth(width);
353  sh = CalcHeight(height, pal);
354  if (nused > 16) sd = 5;
355  else if (nused > 8) sd = 4;
356  else if (nused > 4) sd = 3;
357  else if (nused > 2) sd = 2;
358  else if (nused > 0) sd = 1;
359  else
360  fprintf (stderr, "found 0!! colors\n"), _abort ();
361  if (SW) sw = SW;
362  if (SH) sh = SH;
363  screen.Width = sw, screen.Height = sh, screen.Depth = sd;
364  if (pal) {
365  screen.ViewModes =
366  ((sh > MAX_Y_PAL) ? LACE : 0) | ((sw > MAX_X) ? HIRES : 0);
367  }else{
368  screen.ViewModes =
369  ((sh > MAX_Y_NTSC) ? LACE : 0) | ((sw > MAX_X) ? HIRES : 0);
370  }
371  window.Width = sw, window.Height = sh;
372  } else {
373  isham = TRUE;
374  sd = 6;
375  sw = CalcHAMWidth(width);
376  sh = CalcHeight(height, pal);
377  if (SW) sw = SW;
378  if (SH) sh = SH;
379  screen.Width = sw, screen.Height = sh, screen.Depth = sd;
380  if (pal) {
381  screen.ViewModes = ((sh > MAX_Y_PAL) ? LACE : 0) | HAM;
382  }else{
383  screen.ViewModes = ((sh > MAX_Y_NTSC) ? LACE : 0) | HAM;
384  }
385  window.Width = sw, window.Height = sh;
386  }
387 
388  for (i=0; i<MENUITEMS; i++) {
389  if (screen.ViewModes & HIRES) {
390  actions[i].Width += COMMWIDTH;
391  }else{
392  actions[i].Width += LOWCOMMWIDTH;
393  }
394  }
395 
396  GetPrefs(&prefs, sizeof(prefs));
397  Ptr = (USHORT *)AllocMem(POINTERSIZE * sizeof(USHORT), MEMF_CHIP);
398  if (!Ptr) {
399  fprintf (stderr, "Can't allocate chip memory for pointer\n");
400  _abort ();
401  }
402 
403  if (threescreens) {
404  if ((s3 = OpenScreen (&screen)) == NULL)
405  fprintf (stderr, "Can't open screen 3\n"), _abort ();
406  AdjustScreen(s3, &dx, &dy);
407  ShowTitle (s3, FALSE);
408  window.Screen = s3;
409  if ((w3 = OpenWindow (&window)) == NULL)
410  fprintf (stderr, "Can't open window 3\n"), _abort ();
411  vp3 = &(s3->ViewPort);
412  rp3 = w3->RPort;
413  SetMenuStrip(w3, &menu);
414 
415  if ((s2 = OpenScreen (&screen)) == NULL)
416  fprintf (stderr, "Can't open screen 2\n"), _abort ();
417  AdjustScreen(s2, &dx, &dy);
418  ShowTitle (s2, FALSE);
419  window.Screen = s2;
420  if ((w2 = OpenWindow (&window)) == NULL)
421  fprintf (stderr, "Can't open window 2\n"), _abort ();
422  vp2 = &(s2->ViewPort);
423  rp2 = w2->RPort;
424  SetMenuStrip(w2, &menu);
425  }
426  if ((s1 = OpenScreen (&screen)) == NULL)
427  fprintf (stderr, "Can't open screen 1\n"), _abort ();
428  AdjustScreen(s1, &dx, &dy);
429  ShowTitle (s1, FALSE);
430  window.Screen = s1;
431  if ((w1 = OpenWindow (&window)) == NULL)
432  fprintf (stderr, "Can't open window 1\n"), _abort ();
433  vp1 = &(s1->ViewPort);
434  rp1 = w1->RPort;
435  SetMenuStrip(w1, &menu);
436 
437  max_y = (GfxBase->DisplayFlags & PAL) ? MAX_Y_PAL : MAX_Y_NTSC;
438  if (s1->ViewPort.Modes & LACE){
439  max_y *= 2;
440  }
441  max_x = MAX_X;
442  if (s1->ViewPort.Modes & HIRES){
443  max_x *= 2;
444  }
445  if (sw <= max_x) {
446  freq.LeftEdge = (sw - FREQW) / 2;
447  }else{
448  freq.LeftEdge = (max_x - FREQW) / 2;
449  }
450  if (sh <= max_y) {
451  freq.TopEdge = (sh - FREQH) / 2;
452  }else{
453  freq.TopEdge = (max_y - FREQH) / 2;
454  }
455 
456  if (isham) nused = 16;
457  for (i = 0; i < nused; i++) {
458  if (threescreens) {
459  SetRGB4 (vp1, (long) i, (long) i, 0L, 0L);
460  SetRGB4 (vp2, (long) i, 0L, (long) i, 0L);
461  SetRGB4 (vp3, (long) i, 0L, 0L, (long) i);
462  }else{
463  SetRGB4 (vp1, (long) i, (long) R[i], (long) G[i], (long) B[i]);
464  }
465  }
466 
467  memcpy(Ptr, RenderPtr, POINTERSIZE * sizeof(USHORT));
468  SetPointer(w1, Ptr, 16, 16, dx - 1, dy);
469  if (threescreens) {
470  SetPointer(w2, Ptr, 16, 16, dx - 1, dy);
471  SetPointer(w3, Ptr, 16, 16, dx - 1, dy);
472  }
473 
474  display_rle ();
475 
476  memcpy(Ptr, prefs.PointerMatrix, POINTERSIZE * sizeof(USHORT));
477  SetPointer(w1, Ptr, 16, 16, dx - 1 + prefs.XOffset, dy + prefs.YOffset);
478  if (threescreens) {
479  SetPointer(w2, Ptr, 16, 16, dx - 1 + prefs.XOffset, dy + prefs.YOffset);
480  SetPointer(w3, Ptr, 16, 16, dx - 1 + prefs.XOffset, dy + prefs.YOffset);
481  }
482 
483  if (fnam[0]) {
484 #ifndef NOIFFLIB
485  if (IFFBase) save();
486 #else
487  save();
488 #endif
489  }else{
490  done = (UBYTE)0;
491  if (threescreens) {
492  signalmask = (1L << w1->UserPort->mp_SigBit) |
493  (1L << w2->UserPort->mp_SigBit) |
494  (1L << w3->UserPort->mp_SigBit);
495  }else{
496  signalmask = 1L << w1->UserPort->mp_SigBit;
497  }
498 
499  if (threescreens) { /* Run at high priority to reduce flicker */
500  SetTaskPri(FindTask(0L), 20L);
501  }
502  while (!done) {
503  if (threescreens) {
504  if (!(havemenu || havereq)) {
505  ScreenToFront(s1);
506  }
507  done = handleIDCMP();
508  if (!(havemenu || havereq)) {
509  ScreenToFront(s2);
510  }
511  done |= handleIDCMP();
512  if (!(havemenu || havereq)) {
513  ScreenToFront(s3);
514  }
515  done |= handleIDCMP();
516  }
517  if (!threescreens || havemenu || havereq) {
518  signals = Wait(signalmask);
519  if (signals & signalmask) {
520  done = handleIDCMP();
521  }
522  }
523  }
524  }
525  _abort ();
526 }
527 
528 int
529 compare (struct cuse *a, struct cuse *b)
530 {
531  if (a->j < b->j)
532  return 1;
533  else if (a->j > b->j)
534  return -1;
535  else
536  return 0;
537 }
538 
539 int
540 find_most_used (void)
541 {
542  rle_hdr rle_f_hdr;
543  char comi[4][100];
544  char *como;
545  unsigned char r, g, b;
546  int ncolors, i, j, x, y, packed, pix, col;
547 
548  rle_f_hdr.rle_file = ifd;
549  if (rle_get_setup(&rle_f_hdr) < 0)
550  return -1;
551 
552  RLE_CLR_BIT (rle_f_hdr, RLE_ALPHA);
553  for (i = 3; i < rle_f_hdr.ncolors; i++)
554  RLE_CLR_BIT (rle_f_hdr, i);
555 
556  ncolors = rle_f_hdr.ncolors > 3 ? 3 : rle_f_hdr.ncolors;
557  if (ncolors == 2)
558  return -1;
559 
560  height = rle_f_hdr.ymax - rle_f_hdr.ymin + 1;
561  width = rle_f_hdr.xmax - rle_f_hdr.xmin + 1;
562 
563  depth = 0, packed = 0;
564  if ((como = rle_getcom ("cy_depth", &rle_f_hdr)) != NULL) {
565  depth = atoi (como);
566  if ((como = rle_getcom ("cy_width", &rle_f_hdr)) != NULL)
567  width = atoi (como);
568  como = rle_getcom ("cy_packed", &rle_f_hdr);
569  packed = como ? 1 : 0;
570  }
571  if (!depth)
572  depth = ncolors * 8;
573 
574  for (i = 0; i < 3; i++)
575  if ((sl[i] = (rle_pixel *) malloc(rle_f_hdr.xmax -
576  rle_f_hdr.xmin + 1)) == NULL) {
577  for (j = 0; j < i; j++)
578  free ((char *) sl[j]);
579  return -1;
580  }
581 
582  rle_f_hdr.xmax -= rle_f_hdr.xmin, rle_f_hdr.xmin = 0;
583 
585  rle_dflt_hdr.alpha = 0;
587  rle_dflt_hdr.ncmap = rle_f_hdr.ncmap;
588  rle_dflt_hdr.cmaplen = rle_f_hdr.cmaplen;
589  rle_dflt_hdr.cmap = rle_f_hdr.cmap;
590  rle_dflt_hdr.comments = NULL;
592  rle_dflt_hdr.xmin = 0;
593  rle_dflt_hdr.xmax = width - 1;
594  rle_dflt_hdr.ymin = 0;
596  rle_dflt_hdr.ncolors = ncolors;
597  for (i = 0; i < MIN (3, ncolors); i++)
599  for (i = MIN (3, ncolors); i < ncolors; i++)
602 
603  if (packed) {
604  sprintf (comi[0], "cy_depth=%d", depth), rle_putcom (comi[0], &rle_dflt_hdr);
605  sprintf (comi[1], "cy_width=%d", width), rle_putcom (comi[1], &rle_dflt_hdr);
606  strcpy (comi[2], "cy_packed=1"), rle_putcom (comi[2], &rle_dflt_hdr);
607  }
608 
609  cmap = buildmap (&rle_f_hdr, 3, 1.0, 0.0);
610 
612 
613  while ((y = rle_getrow(&rle_f_hdr, sl)) <= rle_f_hdr.ymax) {
615  y -= rle_f_hdr.ymin;
616  if (ncolors == 3) {
617  for (x = 0; x < width; x++)
618  r = sl[0][x], g = sl[1][x], b = sl[2][x], cusage[index(r, g, b)].j++;
619  } else if (ncolors == 1 && !packed) {
620  for (x = 0; x < width; x++) {
621  r = cmap[0][sl[0][x]];
622  g = cmap[1][sl[0][x]];
623  b = cmap[2][sl[0][x]];
624  cusage[index(r, g, b)].j++;
625  }
626  } else {
627  for (col = 0, x = 0; x < width; col = (col + 1) & 7, x++) {
628  pix = (sl[0][x / 8] & (1 << (7 - col))) ? 0: 255;
629  r = pix, g = pix, b = pix, cusage[index(r, g, b)].j++;
630  }
631  }
632  }
633  for (i = 0; i < 3; i++)
634  free((char *) sl[i]);
635 
636  nused = 0;
637  for (i = 0; i < 4096; i++) {
638  cusage[i].i = i;
639  if (cusage[i].j)
640  nused++;
641  }
642  printf ("colors used: %d\n", nused);
643 
644  qsort ((char *) cusage, 4096, sizeof (struct cuse), compare);
645 
646  if (threescreens) {
647  nused = 16;
648  return 0;
649  }
650  if (bw) {
651  for (i = 0; i < 16; i++) {
652  R[i] = G[i] = B[i] = i;
653  nused = 16;
654  }
655  return 0;
656  }
657  if (nused <= 32) {
658  for (i = 0; i < 32; i++) {
659  R[i] = (cusage[i].i >> 8) & 0xf;
660  G[i] = (cusage[i].i >> 4) & 0xf;
661  B[i] = cusage[i].i & 0xf;
662  }
663  return 0;
664  }
665 
666 #if 0
667  nleft = nused;
668  for (i = nused - 1; i >= 0; i--) {
669  if (nleft <= 16)
670  break;
671  for (j = 0; j < i; j++)
672  if (rdist (i, j) + gdist (i, j) + bdist (i, j) <= 1) {
673  cusage[i].j = 0, nleft--;
674  break;
675  }
676  }
677  printf ("colors left %d\n", nleft);
678 #endif
679 
680  for (i = 0, j = 0; j < 16 && i < nused; i++)
681  if (cusage[i].j) {
682  R[j] = (cusage[i].i >> 8) & 0xf;
683  G[j] = (cusage[i].i >> 4) & 0xf;
684  B[j] = cusage[i].i & 0xf;
685  j++;
686  }
687 
688  return 0;
689 }
690 
691 static int x, y;
692 static unsigned char r, g, b;
693 
694 int
695 display_rle (void)
696 {
697  rle_hdr rle_f_hdr;
698  char *como;
699  int ncolors, i, j, packed, pix, col;
700 
701  rle_f_hdr.rle_file = tfd;
702  if (rle_get_setup(&rle_f_hdr) < 0)
703  return -1;
704 
705  RLE_CLR_BIT (rle_f_hdr, RLE_ALPHA);
706  for (i = 3; i < rle_f_hdr.ncolors; i++)
707  RLE_CLR_BIT (rle_f_hdr, i);
708 
709  ncolors = rle_f_hdr.ncolors > 3 ? 3 : rle_f_hdr.ncolors;
710  if (ncolors == 2)
711  return -1;
712 
713  height = rle_f_hdr.ymax - rle_f_hdr.ymin + 1;
714  width = rle_f_hdr.xmax - rle_f_hdr.xmin + 1;
715 
716  depth = 0, packed = 0;
717  if ((como = rle_getcom ("cy_depth", &rle_f_hdr)) != NULL) {
718  depth = atoi (como);
719  if ((como = rle_getcom ("cy_width", &rle_f_hdr)) != NULL)
720  width = atoi (como);
721  como = rle_getcom ("cy_packed", &rle_f_hdr);
722  packed = como ? 1 : 0;
723  }
724  if (!depth)
725  depth = ncolors * 8;
726  offsetx = (sw - width) / 2;
727  offsety = (sh - height) / 2;
728 
729  for (i = 0; i < 3; i++)
730  if ((sl[i] = (rle_pixel *) malloc(rle_f_hdr.xmax -
731  rle_f_hdr.xmin + 1)) == NULL) {
732  for (j = 0; j < i; j++)
733  free ((char *) sl[j]);
734  return -1;
735  }
736 
737  rle_f_hdr.xmax -= rle_f_hdr.xmin, rle_f_hdr.xmin = 0;
738 
739  while ((y = rle_getrow(&rle_f_hdr, sl)) <= rle_f_hdr.ymax) {
740  if (handleIDCMP()) {
741  _abort();
742  }
743  y -= rle_f_hdr.ymin;
744  if (ncolors == 3) {
745  for (x = 0; x < width; x++)
746  r = sl[0][x], g = sl[1][x], b = sl[2][x], show_rgb ();
747  } else if (ncolors == 1 && !packed) {
748  for (x = 0; x < width; x++) {
749  r = cmap[0][sl[0][x]];
750  g = cmap[1][sl[0][x]];
751  b = cmap[2][sl[0][x]];
752  show_rgb ();
753  }
754  } else {
755  for (col = 0, x = 0; x < width; col = (col + 1) & 7, x++) {
756  pix = (sl[0][x / 8] & (1 << (7 - col))) ? 0: 255;
757  r = pix, g = pix, b = pix, show_rgb ();
758  }
759  }
760  }
761  for (i = 0; i < 3; i++)
762  free((char *) sl[i]);
763 
764  return 0;
765 }
766 
767 void
768 show_rgb (void)
769 {
770  int xx, yy, i, j;
771  long d, td, d1, d2, d3, rd, gd, bd;
772 
773  static unsigned char pr, pg, pb;
774 
775  xx = mapx (x);
776  if (!flip) {
777  yy = mapy (y);
778  }else{
779  yy = fmapy (y);
780  }
781  if (!inside (xx, yy))
782  return;
783 
784  if (bw) {
785 #if 0
786  r = g = b = 0.35 * r + 0.55 * g + 0.10 * b;
787 #else
788  r = g = b = (35 * r + 55 * g + 10 * b) / 100;
789 #endif
790  }
791 #ifndef AZTEC_C
792  r >>= 4, g >>= 4, b >>= 4;
793 #else /* avoid a manx bug */
794  r = (r >> 4) & 0xf, g = (g >> 4) & 0xf, b = (b >> 4) & 0xf;
795 #endif
796  if (threescreens) {
797  OptSetAPen1 (rp1, (long) r); OptWritePixel1 (rp1, (long) xx, (long) yy);
798  OptSetAPen2 (rp2, (long) g); OptWritePixel2 (rp2, (long) xx, (long) yy);
799  OptSetAPen3 (rp3, (long) b); OptWritePixel3 (rp3, (long) xx, (long) yy);
800  return;
801  }
802  if (!isham) {
803  for (i = 0; i < nused; i++) {
804  if (R[i] == (int) r && G[i] == (int) g && B[i] == (int) b) {
805  OptSetAPen1 (rp1, (long) i); OptWritePixel1 (rp1, (long) xx, (long) yy);
806  break;
807  }
808  }
809  return;
810  }
811  for (i = 0, d = 3276700, j = -1; i < 16; i++) {
812  td = SQ (r - R[i]) + SQ (g - G[i]) + SQ (b - B[i]);
813  if (td < d)
814  d = td, j = i;
815  if (d == 0)
816  break;
817  }
818  if (d == 0 || x == 0) {
819  OptSetAPen1 (rp1, (long) EXACT (j));
820  pr = R[j], pg = G[j], pb = B[j];
821  } else {
822  rd = SQ (r - pr), gd = SQ (g - pg), bd = SQ (b - pb);
823  d1 = rd + gd, d2 = rd + bd, d3 = gd + bd;
824  if (d <= d1 && d <= d2 && d <= d3) {
825  OptSetAPen1 (rp1, (long) EXACT (j));
826  pr = R[j], pg = G[j], pb = B[j];
827  } else if (d1 <= d2 && d1 <= d3) {
828  OptSetAPen1 (rp1, (long) BLUE (b));
829  pb = b;
830  } else if (d2 <= d3 && d2 <= d1) {
831  OptSetAPen1 (rp1, (long) GREEN (g));
832  pg = g;
833  } else {
834  OptSetAPen1 (rp1, (long) RED (r));
835  pr = r;
836  }
837  }
838  OptWritePixel1 (rp1, (long) xx, (long) yy);
839 }
840 
841 #ifdef MCH_AMIGA
842 void
843 _abort (void)
844 #else
845 int
846 CXBRK (void)
847 #endif
848 {
849  if (ifd && ifd != stdin)
850  fclose (ifd);
851 
852  if (tfd) {
853  fclose (tfd);
854  unlink (tfile);
855  }
856 
857  if (w1) {
858  if (w1->MenuStrip)
859  ClearMenuStrip(w1);
860  CloseWindow (w1);
861  }
862 
863  if (w2) {
864  if (w2->MenuStrip)
865  ClearMenuStrip(w2);
866  CloseWindow (w2);
867  }
868 
869  if (w3) {
870  if (w3->MenuStrip)
871  ClearMenuStrip(w3);
872  CloseWindow (w3);
873  }
874 
875  if (s1)
876  CloseScreen (s1);
877 
878  if (s2)
879  CloseScreen (s2);
880 
881  if (s3)
882  CloseScreen (s3);
883 
884  if (Ptr)
885  FreeMem(Ptr, POINTERSIZE * sizeof(USHORT));
886 
887  if (GfxBase)
888  CloseLibrary ((struct Library *)GfxBase);
889 
890  if (IntuitionBase)
891  CloseLibrary (IntuitionBase);
892 
893 #ifndef NOIFFLIB
894  if (IFFBase)
895  CloseLibrary (IFFBase);
896 #endif
897 
898  exit (0);
899 #ifndef MCH_AMIGA /* Make Lattice shut up */
900  return 1;
901 #endif
902 }
903 
904 UBYTE
905 handleIDCMP(void)
906 {
907  UBYTE flag = 0;
908  struct IntuiMessage *message = NULL;
909  USHORT code, selection;
910  ULONG class, itemnum;
911  int t;
912 
913  while ((message = (struct IntuiMessage *)GetMsg(w1->UserPort)) ||
914  (threescreens && (message=(struct IntuiMessage *)GetMsg(w2->UserPort))) ||
915  (threescreens && (message=(struct IntuiMessage *)GetMsg(w3->UserPort)))) {
916  class = message->Class;
917  code = message->Code;
918  switch (class) {
919  case GADGETUP:
920  flag = 1;
921  break;
922  case REQSET:
923  FixColors();
924  if (threescreens) ScreenToFront(s1);
925  ActivateGadget(&fgad, w1, &freq);
926  break;
927  case REQCLEAR:
928  save();
929  havereq = 0;
930  ResetColors();
931  break;
932  case MENUVERIFY:
933  havemenu = 1;
934  FixColors();
935  break;
936  case MENUPICK:
937  selection = code;
938  while (selection != MENUNULL) {
939  itemnum = ITEMNUM(selection);
940  switch (itemnum) {
941  case 0:
942  if (ifd == stdin) {
943  if (threescreens) ScreenToFront(s1);
944  havereq = 1;
945  Request(&freq, w1);
946  }else{
947  strcpy(fnam, infile);
948  t = strlen(fnam);
949  if ( (t >= 4) && (strcmp(&fnam[t-4], ".rle") == 0)) {
950  fnam[t-4] = '\000';
951  }
952  strcat(fnam, ".ilbm");
953  }
954  save();
955  break;
956  case 1:
957  if (threescreens) ScreenToFront(s1);
958  havereq = 1;
959  Request(&freq, w1);
960  break;
961  case 2:
962  flag = 1;
963  break;
964  default:
965  break;
966  }
967  selection = ((struct MenuItem *)ItemAddress
968  (&menu, (LONG)selection))->NextSelect;
969  }
970  havemenu = 0;
971  ResetColors();
972  break;
973  default:
974  break;
975  }
976  ReplyMsg((struct Message *)message);
977  }
978  return flag;
979 }
980 
981 void
982 save()
983 {
984 #ifndef NOIFFLIB
985  char *name;
986 
987  if (*fnam == '\000')
988  return;
989 
990  if (IFFBase) {
991  ResetColors();
992  if (threescreens) {
993  name = malloc(strlen(fnam) + 4);
994  if (!name) {
995  fprintf(stderr, "malloc failed\n");
996  return;
997  }
998  strcpy(name, fnam);
999  strcat(name, ".r");
1000  SaveBitMap(name, s1->BitMap,vp1->ColorMap->ColorTable,(isham ? 0x81 : 1));
1001  strcpy(name, fnam);
1002  strcat(name, ".g");
1003  SaveBitMap(name, s2->BitMap,vp2->ColorMap->ColorTable,(isham ? 0x81 : 1));
1004  strcpy(name, fnam);
1005  strcat(name, ".b");
1006  SaveBitMap(name, s3->BitMap,vp3->ColorMap->ColorTable,(isham ? 0x81 : 1));
1007  free(name);
1008  }else{
1009  SaveBitMap(fnam, s1->BitMap,vp1->ColorMap->ColorTable,(isham ? 0x81 : 1));
1010  }
1011  FixColors();
1012  }
1013 #endif
1014 }
1015 
1016 void
1017 FixColors()
1018 {
1019  if (threescreens) {
1020  OptSetAPen1(rp1, 1L); OptSetAPen2(rp2, 1L); OptSetAPen3(rp3, 1L);
1021  SetBPen(rp1, 0L); SetBPen(rp2, 0L); SetBPen(rp3, 0L);
1022  SetRGB4(vp1, 1L, 15L, 15L, 15L);
1023  SetRGB4(vp2, 1L, 15L, 15L, 15L);
1024  SetRGB4(vp3, 1L, 15L, 15L, 15L);
1025  }else{
1026  OptSetAPen1(rp1, 1L);
1027  SetBPen(rp1, 0L);
1028  SetRGB4(vp1, 1L, (R[0]+8) % 16, (G[0]+8) % 16, (B[0]+8) % 16);
1029  }
1030 }
1031 
1032 void
1033 ResetColors()
1034 {
1035  if (threescreens) {
1036  SetRGB4(vp1, 1L, 1L, 1L, 1L);
1037  SetRGB4(vp2, 1L, 1L, 1L, 1L);
1038  SetRGB4(vp3, 1L, 1L, 1L, 1L);
1039  }else{
1040  SetRGB4(vp1, 1L, (long)R[1], (long)G[1], (long)B[1]);
1041  }
1042 }
1043 
1044 int
1045 CalcWidth(int width)
1046 {
1047  if (width <= 320) return 320;
1048  if (width <= MAX_X) return width;
1049  if (width <= 640) return 640;
1050  return width;
1051 }
1052 
1053 int
1054 CalcHAMWidth(int width)
1055 {
1056  if (width <= 320) return 320;
1057  return width;
1058 }
1059 
1060 int
1061 CalcHeight(int height, int pal)
1062 {
1063  if (pal) {
1064  if (height <= 256) return 256;
1065  if (height <= MAX_Y_PAL) return height;
1066  if (height <= 512) return 512;
1067  return height;
1068  }else{
1069  if (height <= 200) return 200;
1070  if (height <= MAX_Y_NTSC) return height;
1071  if (height <= 400) return 400;
1072  return height;
1073  }
1074 }
1075 
1076 /*
1077  No-one in his right mind would want to run this program from the Workbench!
1078 */
1079 #ifdef MCH_AMIGA
1080 void
1081 _wb_parse()
1082 {}
1083 #endif
#define MIN(x, y)
Definition: rletopaint.c:53
static unsigned char g
Definition: getami.c:692
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
static unsigned int R[32]
Definition: getami.c:98
int xmin
Definition: rle.h:100
#define mapx(x)
Definition: getami.c:44
static int bw
Definition: getami.c:106
static struct RastPort * rp1
Definition: getami.c:91
static int sh
Definition: getami.c:101
static struct Image img
Definition: getami.c:71
static USHORT * Ptr
Definition: getami.c:109
const char ** comments
Definition: rle.h:113
static struct Window * w1
Definition: getami.c:90
static struct IntuiText ftxt
Definition: getami.c:174
#define ABS(n)
Definition: dvirle1.c:89
#define OptWritePixel3(rp, x, y)
Definition: getami.c:226
int curcol2
Definition: getami.c:218
int curcol1
Definition: getami.c:218
static int threescreens
Definition: getami.c:106
static int sd
Definition: getami.c:101
static int depth
Definition: getami.c:101
#define MENUITEMS
Definition: getami.c:143
static int width
Definition: getami.c:101
#define OptWritePixel2(rp, x, y)
Definition: getami.c:225
#define FREQH
Definition: getami.c:190
static FILE * ifd
Definition: getami.c:100
static unsigned char r
Definition: getami.c:692
void main(int argc, char **argv)
Definition: aliastorle.c:121
static struct Gadget fgad
Definition: getami.c:184
static struct ViewPort * vp2
Definition: getami.c:95
static struct Window * w3
Definition: getami.c:90
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
static char ufnam[80]
Definition: getami.c:168
#define fmapy(y)
Definition: getami.c:46
rle_map * cmap
Definition: rle.h:112
static struct NewScreen screen
Definition: getami.c:67
int rle_getrow(rle_hdr *the_hdr, scanline)
Definition: rle_getrow.c:333
static int nused
Definition: getami.c:101
int j
Definition: getami.c:87
char * mktemp(char *)
Definition: mktemp.c:7
static struct Screen * s3
Definition: getami.c:94
static int havereq
Definition: getami.c:106
int curcol3
Definition: getami.c:218
#define MAX_X
Definition: AdjustScreen.c:7
#define EXACT(x)
Definition: getami.c:48
static struct Menu menu
Definition: getami.c:163
static FILE * tfd
Definition: getami.c:100
static int offsety
Definition: getami.c:105
static int height
Definition: getami.c:101
int ymin
Definition: rle.h:100
int optind
Definition: getopt.c:30
static rle_pixel ** cmap
Definition: getami.c:97
static struct StringInfo fgadinfo
Definition: getami.c:170
static char * tfile
Definition: getami.c:99
static int y
Definition: getami.c:691
static struct Window * w2
Definition: getami.c:90
static struct NewWindow window
Definition: getami.c:80
#define OptSetAPen2(rp, col)
Definition: getami.c:221
#define MAX_Y_PAL
Definition: AdjustScreen.c:9
static int sw
Definition: getami.c:101
static unsigned char b
Definition: getami.c:692
static unsigned int B[32]
Definition: getami.c:98
static rle_pixel * sl[3]
Definition: getami.c:96
rle_pixel ** buildmap(rle_hdr *the_hdr, int minmap, double orig_gamma, double new_gamma)
Definition: buildmap.c:56
#define SQ(x)
Definition: getami.c:52
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
enum rle_dispatch dispatch
Definition: rle.h:99
#define index
Definition: rle_config.h:96
struct Library * IntuitionBase
Definition: show3.c:20
static int x
Definition: getami.c:691
static struct RastPort * rp3
Definition: getami.c:91
int i
Definition: getami.c:87
static struct RastPort * rp2
Definition: getami.c:91
static struct IntuiText txt[]
Definition: getami.c:145
static struct ViewPort * vp3
Definition: getami.c:95
static int havemenu
Definition: getami.c:106
static int isham
Definition: getami.c:101
static int forceham
Definition: getami.c:107
#define BASENAME(x)
Definition: getami.c:58
#define _abort
Definition: getami.c:208
#define GREEN(x)
Definition: getami.c:50
char * rle_getcom(char *name, rle_hdr *the_hdr) const
Definition: rle_getcom.c:81
static int SQtmp
Definition: getami.c:133
struct Library * IFFBase
Definition: show3.c:20
static unsigned int G[32]
Definition: getami.c:98
#define mapy(y)
Definition: getami.c:45
#define FREQW
Definition: getami.c:189
int background
Definition: rle.h:100
#define RLE_CLR_BIT(glob, bit)
Definition: rle.h:124
int ncmap
Definition: rle.h:100
#define inside(x, y)
Definition: getami.c:47
int ymax
Definition: rle.h:100
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
static int flip
Definition: getami.c:106
const char * rle_putcom(char *value, rle_hdr *the_hdr) const
Definition: rle_putcom.c:82
int cmaplen
Definition: rle.h:100
#define BLUE(x)
Definition: getami.c:51
static struct Border fbord
Definition: getami.c:180
int alpha
Definition: rle.h:100
#define RLE_ALPHA
Definition: rle.h:65
static struct Requester freq
Definition: getami.c:192
#define OptSetAPen3(rp, col)
Definition: getami.c:222
#define OptSetAPen1(rp, col)
Definition: getami.c:220
static int offsetx
Definition: getami.c:105
char * optarg
Definition: getopt.c:29
static struct Screen * s2
Definition: getami.c:93
static struct Screen * s1
Definition: getami.c:92
static struct MenuItem actions[]
Definition: getami.c:151
static char fnam[80]
Definition: getami.c:167
static char * infile
Definition: getami.c:99
#define RED(x)
Definition: getami.c:49
Definition: getami.c:86
static struct ViewPort * vp1
Definition: getami.c:95
rle_hdr rle_dflt_hdr
Definition: rle_global.c:66
static struct Gadget CloseGadget
Definition: getami.c:75
#define OptWritePixel1(rp, x, y)
Definition: getami.c:224
FILE * rle_file
Definition: rle.h:114
#define MAX_Y_NTSC
Definition: AdjustScreen.c:8
int ncolors
Definition: rle.h:100