home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 568b.lha / PowerSource_v3.0 / source.lzh / source / rim.c < prev    next >
C/C++ Source or Header  |  1991-09-15  |  11KB  |  289 lines

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