home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 514b.lha / GadgetED_v2.3 / Source / rim.c < prev    next >
C/C++ Source or Header  |  1991-06-08  |  10KB  |  286 lines

  1. /*----------------------------------------------------------------------*
  2.   rim.c Version 2.3 -  © Copyright 1990-91 Jaba Development
  3.  
  4.   Author    : Jan van den Baard
  5.   Purpose   : reading routines for IFF ILBM images and ColorMaps
  6.  *----------------------------------------------------------------------*/
  7.  
  8. extern struct ge_prefs     prefs;
  9. extern struct Screen      *MainScreen;
  10. extern struct MemoryChain  Memory;
  11.  
  12. /*
  13.  * check to see if there are bit-planes that doesn't contain data
  14.  */
  15. static BOOL check(data,size)
  16.     UBYTE *data;
  17.     ULONG size;
  18. {
  19.     register UBYTE *pointer;
  20.     register UCOUNT counter;
  21.  
  22.     pointer = data;
  23.     for(counter=0;counter<size;counter++) if(*pointer++) return(TRUE);
  24.     return(FALSE);
  25. }
  26.  
  27. /*
  28.  * filter out the bit-planes that doesn't contain data
  29.  */
  30. VOID skip_zero_planes(image)
  31.     struct Image *image;
  32. {
  33.     UBYTE depth = 0;
  34.     ULONG plane_size;
  35.     UBYTE  *data, *planes[8], *data1;
  36.     register UCOUNT counter,ptc = 0;
  37.  
  38.     plane_size = RASSIZE(image->Width,image->Height);
  39.     data       = (UBYTE *)image->ImageData;
  40.  
  41.     for(counter = 0; counter < image->Depth; counter++)
  42.     {   planes[counter] = (UBYTE *)(data + (counter * plane_size));
  43.         if(check(planes[counter],plane_size)) depth++;
  44.     }
  45.  
  46.     if(depth == image->Depth) return;
  47.     if(NOT(data1 = (UBYTE *)
  48.       AllocMem((ULONG)depth * plane_size,MEMF_CHIP+MEMF_CLEAR))) return;
  49.  
  50.     for(counter = 0; counter < image->Depth; counter++)
  51.     {   if(check(planes[counter],plane_size))
  52.         CopyMem((char *)planes[counter],(char *)(data1+(ptc++ * plane_size)),plane_size);
  53.     }
  54.     image->PlanePick = NULL;
  55.     for(counter = 0; counter < depth; counter++ )
  56.     image->PlanePick |= (1 << counter);
  57.     FreeMem(data,(plane_size * image->Depth));
  58.     image->Depth = depth;
  59.     image->ImageData = (USHORT *)data1;
  60. }
  61.  
  62. /*
  63.  * check to see if the file opened is an IFF ILBM file
  64.  */
  65. static BOOL CheckIFF(file)
  66.     BPTR file;
  67. {
  68.     struct FORMChunk   fchunk;
  69.     char              *str = NULL;
  70.  
  71.     if(Read(file,(char *)&fchunk,sizeof(struct FORMChunk)) <= 0)
  72.         str = "Error during Image Read !";
  73.     else if(fchunk.fc_Type != 'FORM')
  74.         str = "File is not an IFF FORM !";
  75.     else if(fchunk.fc_SubType != 'ILBM')
  76.         str = "IFF FORM is not an ILBM !";
  77.     if(str)
  78.     {   enable_window();
  79.         Error(str);
  80.         return(FALSE);
  81.     }
  82.  return(TRUE);
  83. }
  84.  
  85. /*
  86.  * read the IFF ILBM file into memory and if no errors occur
  87.  * return the pointer to an image structure containing the image
  88.  */
  89. struct Image *ReadImage(ilbmname)
  90.     UBYTE  *ilbmname;
  91. {
  92.     struct IFFChunk     ichunk;
  93.     struct BitMapHeader header;
  94.     BPTR                infile = NULL;
  95.     ULONG               length, offset = NULL, unpacked;
  96.     struct Image        *image = NULL;
  97.     ULONG               planes_size,ps;
  98.     COUNT               plane,row;
  99.     BYTE                *s1,i;
  100.     BYTE                *source, *dest, *planedata = NULL, *planes[8], byte, byte1;
  101.     BOOL                GotBODY = FALSE;
  102.     char                *str;
  103.  
  104.     buisy();
  105.     if(NOT(image = (struct Image *)Alloc(&Memory,(ULONG)sizeof(struct Image))))
  106.     {   str = "Out of memory !";
  107.         goto Err;
  108.     }
  109.  
  110.     if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE)))
  111.     {   str = "Can't open IFF file !";
  112.         goto Err;
  113.     }
  114.  
  115.     if(NOT CheckIFF(infile))
  116.     {   FreeItem(&Memory,image,(long)sizeof(struct Image));
  117.         Close(infile);
  118.         return(NULL);
  119.     }
  120.  
  121.     while(GotBODY == FALSE)
  122.     {   if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0)
  123.         {   str = "Error during Image Read !";
  124.         }
  125.         length = ichunk.ic_Length;
  126.         if(length & 1) length++;
  127.         switch(ichunk.ic_Type)
  128.         {    case 'BMHD': if(Read(infile,(char *)&header,length) <= 0)
  129.                           {   str = "Error during Image Read !";
  130.                               goto Err;
  131.                           }
  132.  
  133.                           image->Width      = header.w;
  134.                           image->Height     = header.h;
  135.                           image->Depth      = header.nPlanes;
  136.                           for(i=0;i<image->Depth;i++)
  137.                                image->PlanePick += (1 << i);
  138.                           image->PlaneOnOff = 0x00;
  139.                           ps = RASSIZE(image->Width,image->Height);
  140.                           planes_size = ps * image->Depth;
  141.                           break;
  142.  
  143.              case 'BODY': GotBODY = TRUE;
  144.                           if(NOT(planedata = (BYTE *)AllocMem(planes_size,MEMF_CHIP+MEMF_CLEAR)))
  145.                           {   str = "Out of CHIP memory !";
  146.                               goto Err;
  147.                           }
  148.  
  149.                           for(i=0;i<image->Depth;i++)
  150.                           planes[i] = (BYTE *)(planedata + (i * ps));
  151.  
  152.                           if(header.compression == 0)
  153.                           {   for(row=0;row<image->Height;row++)
  154.                               {   for(plane=0;plane<image->Depth;plane++)
  155.                                   {   if(Read(infile,(char *)planes[plane]+offset,
  156.                                               bpr(image->Width)) <= 0)
  157.                                       {   str = "Error during Image Read !";
  158.                                           goto Err;
  159.                                       }
  160.                                   }
  161.                                   offset += bpr(image->Width);
  162.                               }
  163.                           }
  164.                           else if(header.compression == 1)
  165.                           {   if(NOT(s1 = source = (BYTE *)AllocMem(length,MEMF_PUBLIC+MEMF_CLEAR)))
  166.                               {   str = "Out of memory !";
  167.                                   goto Err;
  168.                               }
  169.  
  170.                               if(Read(infile,(char *)source,length) <= 0)
  171.                               {   FreeMem(source,length);
  172.                                   str = "Error during Image Read !";
  173.                                   goto Err;
  174.                               }
  175.  
  176.                               for(row=0;row<image->Height;row++)
  177.                               {   for(plane=0;plane<image->Depth;plane++)
  178.                                   {   dest = (BYTE *)planes[plane]+offset;
  179.                                       unpacked = bpr(image->Width);
  180.                                       while(unpacked > 0)
  181.                                       {   byte = *source++;
  182.                                           if(byte == 128) {}
  183.                                           else if(byte > 0)
  184.                                           {   byte += 1;
  185.                                               unpacked -= byte;
  186.                                               while(--byte >= 0) *dest++ = *source++;
  187.                                           }
  188.                                           else
  189.                                           {   byte = -byte + 1;
  190.                                               unpacked -= byte;
  191.                                               byte1 = *source++;
  192.                                               while(--byte >= 0) *dest++ = byte1;
  193.                                           }
  194.                                       }
  195.                                   }
  196.                                   offset += bpr(image->Width);
  197.                               }
  198.                               FreeMem(s1,length);
  199.                           }
  200.                           else
  201.                           {   str = "Unknown Image compression !";
  202.                               goto Err;
  203.                           }
  204.                           break;
  205.              default:     Seek(infile,length,OFFSET_CURRENT); break;
  206.         }
  207.     }
  208.     image->ImageData       = (USHORT *)planedata;
  209.     if(prefs.skip_zero_planes) skip_zero_planes(image);
  210.  
  211.     Close(infile);
  212.     ok();
  213.     return(image);
  214.  
  215. Err:
  216.     enable_window();
  217.     Error(str);
  218.     if(infile)      Close(infile);
  219.     if(image)       FreeItem(&Memory,image,(long)sizeof(struct Image));
  220.     if(planedata)   FreeMem(planedata,planes_size);
  221.     return(NULL);
  222. }
  223.  
  224. /*
  225.  * read and set the CMAP of an IFF ILBM file
  226.  */
  227. VOID ReadCMAP(ilbmname)
  228.     UBYTE  *ilbmname;
  229. {
  230.     struct IFFChunk     ichunk;
  231.     BPTR                infile;
  232.     LONG                length;
  233.     register COUNT      reg,i=0;
  234.     BOOL                GotIt = FALSE, GotCMAP = FALSE;
  235.     UBYTE               colors[96],count;
  236.  
  237.     buisy();
  238.     if(NOT(infile = Open((char *)ilbmname,MODE_OLDFILE)))
  239.     {   enable_window();
  240.         Error("Can't open IFF file !");
  241.         return;
  242.     }
  243.  
  244.     if(NOT CheckIFF(infile))
  245.     {   Close(infile);
  246.         return;
  247.     }
  248.  
  249.     while(GotIt == FALSE)
  250.     {    if(Read(infile,(char *)&ichunk,sizeof(struct IFFChunk)) <= 0)
  251.          {   enable_window();
  252.              Error("Error during CMAP read !");
  253.              Close(infile);
  254.              return;
  255.          }
  256.          length = ichunk.ic_Length;
  257.          if(length & 1) length++;
  258.          switch(ichunk.ic_Type)
  259.          {   case 'CMAP': GotCMAP = TRUE;
  260.                           if(Read(infile,(char *)&colors,length) <= 0)
  261.                           {   enable_window();
  262.                               Error("Error during CMAP read !");
  263.                               break;
  264.                           }
  265.                           count = (1 << MainScreen->BitMap.Depth);
  266.                           for(reg=0;reg<count;reg++,i+=3)
  267.                           {    SetRGB4(&MainScreen->ViewPort,
  268.                                        reg,
  269.                                        ((colors[i] >> 4)   & 0x0f),
  270.                                        ((colors[i+1] >> 4) & 0x0f),
  271.                                        ((colors[i+2] >> 4) & 0x0f));
  272.                           }
  273.                           break;
  274.              case 'BODY': GotIt = TRUE; break;
  275.              default:     Seek(infile,length,OFFSET_CURRENT); break;
  276.          }
  277.     }
  278.     Close(infile);
  279.     if(GotCMAP == FALSE)
  280.     {   enable_window();
  281.         Error("No CMAP chunk found !");
  282.     }
  283.     ok();
  284.     return;
  285. }
  286.