home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d174 / iff2sun.lha / IFF2Sun / iff2sun.c < prev    next >
C/C++ Source or Header  |  1989-02-04  |  8KB  |  344 lines

  1. /*
  2. **      This Program created (under tremendous pressure) by Steve Berry.
  3. **
  4. **      I hope you guys keep it clean. (If you don't, let me know :-)
  5. **
  6. **      Status: PD all the way.
  7. **
  8. **      What's it do? This little guy reads an Amiga IFF ILBM file and 
  9. **      outputs sun rasterfile format. GIGO (Georgous In Garbage Out).
  10. **
  11. **    USEAGE: iff2sun infile outfile
  12. **        if infile is not specified stdin is used.
  13. **        if outfile is not specified then stdout is used.
  14. **
  15. **    Note: this program outputs a COLOR sun file with no color table,
  16. **    which defaults to shades of gray. If you want to display this on
  17. **    a monochrome tube (which is what I have) you should go through the
  18. **    folowing steps:
  19. **        1) iff2sun inputfile outputfile
  20. **        2) rastrepl outputfile output.bigger
  21. **        3) rasfilter8to1 -d output.bigger output.mono
  22. **    The rastrepl just pixel replicates the image so that it large
  23. **    enough to see the detail. you can run this as many times as you
  24. **    like, but remember the image quadruples each time you use it.
  25. **        The rasfilter8to1 program converts the color file (8 bit
  26. **    planes) to mono (1 plane) and does some fancy dithering (-d).
  27. **
  28. **    Limitations:
  29. **        Don't do HAM or ExtraHalfBright. I am planning on adding
  30. **        EHB because it would be relitively simple to do, and 64
  31. **        colors would improve the image quality for the dithering
  32. **        routines.
  33. **        Also, I have only tested this on DPaintII images, it is
  34. **        very possible that it might break with other formats.
  35. **        Unlikely, but possible :*)
  36. **
  37. **    CREDITS:
  38. **            Mark Thompson
  39. **            Steve (Raz) Berry
  40. **
  41. **    Contacts:
  42. **            USENET    ...alliant!sberry
  43. **            BIX:    razberry
  44. **
  45. **      10/31/88
  46. */
  47.  
  48. #include <stdio.h>
  49. #include <rasterfile.h>
  50.  
  51. #define HAM 0x800       /* Amiga Viewmodes */
  52. #define HALF 0x80
  53. #define HIRES 0x8000
  54. #define LACE 0x4
  55. #define TRUE 1
  56. #define FALSE 0
  57.  
  58. /* Stupic C needs to be told about functions used before they
  59.    are defined */
  60.  
  61. unsigned char RGBtoLuma();
  62. long parse();
  63.  
  64. /* Some variables and arrays */
  65.  
  66. unsigned char scanline[500][6][128]; /* vert, planes, width (bytes) */
  67. unsigned char coltable[256];
  68. long width, hieght, planes, viewmode, numcolors;
  69. long temp, compress, i, j, k, l;
  70.  
  71. main(argc,argv)
  72. int argc;
  73. char **argv;
  74. {
  75.     struct rasterfile header;
  76.     unsigned char clr;
  77.     long formsize;
  78.     static char chunk[5];
  79.     FILE *inh, *outh;
  80.         
  81.     chunk[4] = 0;
  82.         
  83.     inh = stdin;
  84.     outh = stdout;
  85.     switch (argc) {
  86.         case 0:
  87.             exit(0);
  88.         case 1:
  89.             break;
  90.         case 2:
  91.             inh = fopen(argv[1],"r");
  92.             break;
  93.         case 3:
  94.             inh = fopen(argv[1],"r");
  95.             outh = fopen(argv[2],"w");
  96.             break;
  97.         default:
  98.             printf("Useage %s: infile outfile, or stdio\n", 
  99.                 argv[0]);
  100.             exit(0);
  101.             break;
  102.     }
  103.         
  104.     if (inh == NULL){
  105.         perror(argv[1]);
  106.         exit(-10);
  107.     }        
  108.  
  109.     if (outh == NULL){
  110.         perror(argv[2]);
  111.         exit(-10);
  112.     }        
  113.  
  114.     /* Now comes the fun part... Reading the ILBM's */
  115.         
  116.     if (parse(inh,"FORM")) {
  117.         perror("I don't think that this is an IFF file");
  118.         exit(-10);
  119.     }
  120.  
  121.     fread(&formsize, 4, 1, inh);    /* length of the FORM */
  122.  
  123.     if (parse(inh,"ILBM")) {
  124.         perror("I don't think that this is an ILBM");
  125.         exit(-10);
  126.     }
  127.  
  128.     if (parse(inh,"BMHD")) { 
  129.         perror("Bad format for ILBM.");
  130.         exit(-10);
  131.     }
  132.  
  133.     cc(chunk);
  134.     fread(chunk, 4, 1, inh);    /* length of the BMHD */
  135.  
  136.     cc(chunk);
  137.     fread(chunk, 2, 1, inh);    /* width of bitmap */
  138.     width = *((short *)chunk);
  139.  
  140.     cc(chunk);
  141.     fread(chunk, 2, 1, inh);    /* Height of bitmap */
  142.     hieght = *((short *)chunk);
  143.  
  144.     fread(chunk, 4, 1, inh);    /* Don't want the orgins */
  145.  
  146.     cc(chunk);
  147.     fread(chunk, 1, 1, inh);    /* # of Planes */
  148.     planes = *((unsigned char *)chunk);
  149.  
  150.     fread(chunk, 1, 1, inh);    /* Ignore the Mask */
  151.  
  152.     cc(chunk);
  153.     fread(chunk, 1, 1, inh);    /* Compression? */
  154.  
  155.     compress = *((unsigned char *)chunk);
  156.  
  157.     fread(chunk, 1, 1, inh);    /* just a pad byte */
  158.  
  159. /***********************************************************************
  160. **    DpaintII does not use the CAMG chunk, so we will have to ignore
  161. **    it for now...
  162. ***********************************************************************/
  163.  
  164.     if (planes == 6) {
  165.         perror("Sorry, I can't do HAM or Halfbright.");
  166.         exit(0);
  167.     } 
  168.  
  169.     if (parse(inh,"CMAP")) {
  170.         perror("Bad format for ILBM, couldn't find Color Map.");
  171.     exit(-10);
  172.     } 
  173.  
  174.     cc(chunk);
  175.     fread(chunk, 4, 1, inh);    /* # of color registers */
  176.     numcolors = *((long *)chunk);
  177.         
  178.     numcolors = numcolors/3 ;
  179.     for (i=0;i<numcolors;i++){
  180.         fread(chunk, 3, 1, inh);
  181.         chunk[3] = 0; chunk[4] = 0; 
  182.         chunk[0] = (chunk[0] >> 4) & 0x0f;
  183.         chunk[2] = (chunk[2] >> 4) & 0x0f;
  184.         chunk[1] = (chunk[1] >> 4) & 0x0f;
  185.         coltable[i] = RGBtoLuma(chunk);
  186.     }
  187.  
  188.     if (numcolors == 2)    /* if a mono image, realign to long word */
  189.         fread(chunk,1,2,inh);
  190.  
  191.     if (parse(inh,"BODY")){
  192.         perror("No BODY data.");
  193.         exit(0);
  194.     }
  195.  
  196.     fread(chunk, 4, 1, inh);    /* length of body */
  197.  
  198.       header.ras_magic= 0x59a66a95;
  199.       header.ras_width= width;
  200.       header.ras_height= hieght;
  201.       header.ras_depth= 8;
  202.       header.ras_length= 0;
  203.       header.ras_type= RT_STANDARD;
  204.       header.ras_maptype= RMT_NONE;
  205.       header.ras_maplength= 0;
  206.  
  207. /* Write out the rasterfile header to the ouput */
  208.  
  209.     fwrite(&header, sizeof(header), 1, outh);
  210.  
  211. /* This part does all the work */
  212.  
  213. /* Either we uncompress the file, or we read it in... */
  214.  
  215.     if (compress == 1)
  216.         uncompress(planes, width, inh);
  217.     else 
  218.         for(k = 0;k<hieght;k++)
  219.             for(i = 0;i<planes;i++) {
  220.                 for(j=0;j<width/8;j++){
  221.                     cc(chunk);
  222.                     if(feof(inh))
  223.                         continue;
  224.                     fread(chunk, 1, 1, inh);
  225.                     scanline[k][i][j] = *((unsigned char *)chunk);
  226.                 }
  227.             }
  228.  
  229. /* Here we take the data and output it (finally!) */
  230.  
  231.     for(j = 0;j<hieght;j++){
  232.         for(i = 0;i<width/8;i++)
  233.             process_pixel(i,j,outh);
  234.     }
  235.     fclose(inh);
  236.     fclose(outh);
  237. } /* end of main */
  238.  
  239. /* The uncompression routine                     */
  240. /* Here we uncompress the data for the number of planes     */
  241. /* and store it in the global array scanline[][][]         */
  242. /* Credits: Leo (the great Caped one) was the originator of the */
  243. /* code I ripped this off from.                 */
  244.  
  245. uncompress(planes, width, inh)
  246. FILE *inh;
  247. long planes, width;
  248. {
  249.     long i,j,count,bytesperrow;
  250.     char len;
  251.     unsigned char byte;
  252.  
  253.     for(i=0;i<hieght;i++){
  254.         for(j=0;j<planes;j++){
  255.             count = 0;
  256.             bytesperrow = width / 8;
  257.             while(bytesperrow > 0){
  258.                 if ((len = getc(inh)) >= 0){
  259.                     bytesperrow -= ++len;
  260.                     fread(&scanline[i][j][count],len,1,inh);
  261.                     count += len;
  262.                 } else if (len == -128)
  263.                     ;
  264.                 else if (len < 0){
  265.                     len = -len + 1;
  266.                     bytesperrow -= len;
  267.                     byte = getc(inh);
  268.                     while(--len >= 0)
  269.                         scanline[i][j][count++] = byte;
  270.                 }
  271.             }
  272.             if(bytesperrow)
  273.                 perror("Compression is messed.");
  274.         }
  275.         
  276.     }
  277. }
  278.  
  279.  
  280. /* RGBtoLuma converts the colortable from the Amiga to Luminance information */
  281. /* This routine was written by Mark Thompson                      */
  282.  
  283. unsigned char RGBtoLuma(color)
  284. unsigned char *color;
  285. {
  286.     unsigned char r, g, b;
  287.     unsigned char grey;
  288.     float fgrey;
  289.  
  290.     r = color[0];
  291.     g = color[1];
  292.     b = color[2];
  293.     fgrey = (0.3 * r + 0.59 * g + 0.11 * b)*16 + 0.5;
  294.     grey = fgrey;
  295.     return grey;
  296. }
  297.  
  298. /* Process the byte for the scanline         */
  299. /* Can you say shift 3 times fast?         */
  300.  
  301. process_pixel(byte,scan,outh)
  302. FILE *outh;
  303. unsigned char byte;
  304. long scan;
  305. {
  306.     long j, i, p, result = 0;
  307.     unsigned char temp;
  308.  
  309.     temp = 0; result = 0;
  310.     for(i=7;i>=0;i--){
  311.         for(p=0;p<planes;p++) 
  312.             result = ((((1 << i) & scanline[scan][p][byte])>>i)<<p) | result;
  313.         result = result & 0x1f;
  314.         temp = coltable[result];
  315.         fwrite(&temp, 1, 1, outh);
  316.         result = 0;
  317.     }
  318. }
  319.  
  320. /* look for a chunk in the file */
  321. long parse(inh, str)
  322. FILE *inh;
  323. char *str;
  324. {
  325.         static char chunk[5];
  326.         chunk[4] = 0;
  327.         while (strncmp(chunk,str,4)!=0){
  328.                 fread(chunk, 4, 1, inh);
  329.                 if(feof(inh)!=0)
  330.                         return TRUE;
  331.         }
  332.         return FALSE;
  333. }
  334.  
  335. /* Clear Chunk variable */
  336.  
  337. cc(chunk)
  338. char chunk[5];
  339. {
  340.     register int i;
  341.     for(i=0;i<5;i++)
  342.         chunk[i] = 0;
  343. }
  344.