Exemplo n.º 1
0
int main(int argc, char **argv)
{
   char *pal_file, *output_dir;

   if (argc != 3)
      usage();

   pal_file = argv[1];
   output_dir = argv[2];

   ReadPalette(pal_file);

   fprintf(stderr, "Reserving special colors...\n");
   BlockIndices();

   fprintf(stderr, "Computing lighting palettes...\n");
   MakeLightPalettes();

   fprintf(stderr, "Computing blend bixlat palettes...\n");
   MakeBlendBiXlat(_blend25, 25, 75);
   MakeBlendBiXlat(_blend50, 50, 50);
   MakeBlendBiXlat(_blend75, 75, 25);

   fprintf(stderr, "Writing %s...\n", output_file);
   WritePalette(output_dir);

   fprintf(stderr, "Done.\n");
   return 0;
}
Exemplo n.º 2
0
static ILboolean ParseChunks(PSP_CTX *ctx)
{
	BLOCKHEAD	Block;
	ILuint		Pos;

	do {
		if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) {
			iPopError();  // Get rid of the erroneous IL_FILE_READ_ERROR.
			break;
		}

		if (ctx->Header.MajorVersion == 3) {
			Block.BlockLen = GetLittleUInt(ctx->io);
		}	else {
			UInt(&Block.BlockLen);
		}

		if ( Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 
			|| Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00 ) {
				break;
		}

		UShort(&Block.BlockID);
		UInt(&Block.BlockLen);

		Pos = SIOtell(ctx->io);

		switch (Block.BlockID)
		{
			case PSP_LAYER_START_BLOCK:
				if (!ReadLayerBlock(ctx))
					return IL_FALSE;
				break;

			case PSP_ALPHA_BANK_BLOCK:
				if (!ReadAlphaBlock(ctx))
					return IL_FALSE;
				break;

			case PSP_COLOR_BLOCK:
				if (!ReadPalette(ctx))
					return IL_FALSE;
				break;

			// Gets done in the next iseek, so this is now commented out.
			//default:
				//SIOseek(ctx->io, Block.BlockLen, IL_SEEK_CUR);
		}

		// Skip to next block just in case we didn't read the entire block.
		SIOseek(ctx->io, Pos + Block.BlockLen, IL_SEEK_SET);

		// @TODO: Do stuff here.

	} while (1);

	return IL_TRUE;
}
Exemplo n.º 3
0
ILboolean ParseChunks(PspLoadState* state, ILimage* image)
{
	BLOCKHEAD	Block;

	do {
		if (image->io.read(&image->io, &Block, 1, sizeof(Block)) != sizeof(Block)) {
			il2GetError();  // Get rid of the erroneous IL_FILE_READ_ERROR.
			return IL_TRUE;
		}
		if (state->Header.MajorVersion == 3)
			Block.BlockLen = GetLittleUInt(&image->io);
		else
			UInt(&Block.BlockLen);

		if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
			Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
				return IL_TRUE;
		}
		UShort(&Block.BlockID);
		UInt(&Block.BlockLen);

		auto Pos = image->io.tell(&image->io);

		switch (Block.BlockID)
		{
			case PSP_LAYER_START_BLOCK:
				if (!ReadLayerBlock(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			case PSP_ALPHA_BANK_BLOCK:
				if (!ReadAlphaBlock(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			case PSP_COLOR_BLOCK:
				if (!ReadPalette(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			// Gets done in the next iseek, so this is now commented out.
			//default:
				//image->io.seek(&image->io, Block.BlockLen, IL_SEEK_CUR);
		}

		// Skip to next block just in case we didn't read the entire block.
		image->io.seek(&image->io, Pos + Block.BlockLen, IL_SEEK_SET);

		// @TODO: Do stuff here.

	} while (1);

	return IL_TRUE;
}
Exemplo n.º 4
0
   virtual bool GetImageInfo(dword header, int limit_size_x, int limit_size_y, C_fixed limit_ratio){

                              //check 'gif8'
      if(header!=0x38464947)
         return false;

      dword offs = fl->Tell();
      fl->Seek(offs+6);

      word wsx, wsy;
      if(!fl->ReadWord(wsx) || !fl->ReadWord(wsy))
         return false;
      size_original_x = size_x = wsx;
      size_original_y = size_y = wsy;

                              //packed fields. bits detail:
                              // 0-2: size of global color table
                              // 3: sort flag
                              // 4-6: color resolution
                              // 7: global color table
      byte packed_fields;
      fl->ReadByte(packed_fields);
                              //background color index
      fl->ReadByte(background);
      byte pixelaspectratio;
      fl->ReadByte(pixelaspectratio);

      bpp = (packed_fields&7) + 1;

                              //read/generate global color map
      if(packed_fields&FLG_GLOBAL_COLOR){
         ReadPalette(global_palette, 1<<bpp);
      }else{
                              //gif standard says to provide an internal default palette:
         for(int i=0; i<256; i++){
            global_palette[i].r = global_palette[i].g = global_palette[i].b = byte(i);
            global_palette[i].a = 0xff;
         }
      }
      beg_anim_file_offset = fl->Tell();
      //dword color_res = (packed_fields>>4) & 7;
      //assert(!decoded_rect.x && !decoded_rect.y && decoded_rect.sx==sx && decoded_rect.sy==sy);
      //is_animated = (frame_persist_time>0);
      return true;
   }
Exemplo n.º 5
0
int imFileFormatLED::ReadImageInfo(int index)
{
  (void)index;

  this->palette_count = this->pal_count;

  if (ReadPalette() != IM_ERR_NONE)
    return IM_ERR_ACCESS;

  imBinFileReadInteger(handle, &this->width);
  imBinFileReadInteger(handle, &this->height);
 
  if (imBinFileError(handle))
    return IM_ERR_ACCESS;

  this->file_data_type = IM_BYTE;
  this->file_color_mode = IM_MAP;
  this->file_color_mode |= IM_TOPDOWN;

  return IM_ERR_NONE;
}
Exemplo n.º 6
0
int imFileFormatAVI::ReadImageInfo(int index)
{
  this->current_frame = index;

  if (this->frame)       // frame reading already prepared
    return IM_ERR_NONE;

  /* get stream format */
  LONG formsize;
  AVIStreamReadFormat(stream, 0, NULL, &formsize);
  BITMAPINFO *bmpinfo = (BITMAPINFO*)malloc(formsize);
  HRESULT hr = AVIStreamReadFormat(stream, 0, bmpinfo, &formsize);
  if (hr != 0)
  {
    free(bmpinfo);
    return IM_ERR_ACCESS;
  }

  int top_down = 0;
  if (bmpinfo->bmiHeader.biHeight < 0)
    top_down = 1;

  this->width = bmpinfo->bmiHeader.biWidth;
  this->height = top_down? -bmpinfo->bmiHeader.biHeight: bmpinfo->bmiHeader.biHeight;

  int bpp = bmpinfo->bmiHeader.biBitCount;

  imAttribTable* attrib_table = AttribTable();
  attrib_table->Set("FPS", IM_FLOAT, 1, &fps);

  this->file_data_type = IM_BYTE;

  if (bpp > 8)
  {
    this->file_color_mode = IM_RGB;
    this->file_color_mode |= IM_PACKED;
  }
  else
  {
    this->palette_count = 1 << bpp;
    this->file_color_mode = IM_MAP;
  }

  if (bpp < 8)
    this->convert_bpp = bpp;

  if (bpp == 32)
    this->file_color_mode |= IM_ALPHA;

  if (top_down)
    this->file_color_mode |= IM_TOPDOWN;

  if (bpp <= 8)
  {
    /* updates the palette_count based on the number of colors used */
    if (bmpinfo->bmiHeader.biClrUsed != 0 && 
        (int)bmpinfo->bmiHeader.biClrUsed < this->palette_count)
      this->palette_count = bmpinfo->bmiHeader.biClrUsed;

    ReadPalette((unsigned char*)bmpinfo->bmiColors);
  }

  free(bmpinfo);

  this->line_buffer_extra = 4; // room enough for padding

  /* prepares to read data from the stream */
  if (bpp == 32 || bpp == 16)
  {
    BITMAPINFOHEADER info;
    memset(&info, 0, sizeof(BITMAPINFOHEADER));
    info.biSize = sizeof(BITMAPINFOHEADER);
    info.biWidth = width;
    info.biHeight = height;
    info.biPlanes = 1;
    info.biBitCount = (WORD)bpp;
    frame = AVIStreamGetFrameOpen(stream, &info);
  }
  else
    frame = AVIStreamGetFrameOpen(stream, NULL);

  if (!frame)
    return IM_ERR_ACCESS;

  return IM_ERR_NONE;
}
Exemplo n.º 7
0
int imFileFormatBMP::ReadImageInfo(int index)
{
  (void)index;
  unsigned int dword;

  this->file_data_type = IM_BYTE;

  if (this->is_os2)
  {
    short word;

    /* reads the image width */
    imBinFileRead(handle, &word, 1, 2);
    this->width = (int)word;

    /* reads the image height */
    imBinFileRead(handle, &word, 1, 2);
    this->height = (int)((word < 0)? -word: word);

    dword = word; // it will be used later
  }
  else
  {
    /* reads the image width */
    imBinFileRead(handle, &dword, 1, 4);
    this->width = (int)dword;

    /* reads the image height */
    imBinFileRead(handle, &dword, 1, 4);
    this->height = (int)dword;
    if (this->height < 0)
      this->height = -this->height;
  }

  /* jump 2 bytes (planes) */
  imBinFileSeekOffset(handle, 2);

  /* reads the number of bits per pixel */
  imBinFileRead(handle, &this->bpp, 1, 2);

  if (imBinFileError(handle))
    return IM_ERR_ACCESS;

  // sanity check
  if (this->bpp != 1 && this->bpp != 4 && this->bpp != 8 && 
      this->bpp != 16 && this->bpp != 24 && this->bpp != 32)
    return IM_ERR_DATA;

  // another sanity check
  if (this->comp_type == BMP_BITFIELDS && this->bpp != 16 && this->bpp != 32)
    return IM_ERR_DATA;

  if (this->bpp > 8)
  {
    this->file_color_mode = IM_RGB;
    this->file_color_mode |= IM_PACKED;
  }
  else
  {
    this->palette_count = 1 << bpp;
    this->file_color_mode = IM_MAP;
  }

  if (this->bpp < 8)
    this->convert_bpp = this->bpp;

  if (this->bpp == 32)
    this->file_color_mode |= IM_ALPHA;

  if (dword < 0)
    this->file_color_mode |= IM_TOPDOWN;

  this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 4);
  this->line_buffer_extra = 4; // room enough for padding

  if (this->is_os2)
  {
    if (this->bpp < 24)
      return ReadPalette();

    return IM_ERR_NONE;
  }

  /* we already read the compression information */
  /* jump 8 bytes (compression, image size) */
  imBinFileSeekOffset(handle, 8);

  /* read the x resolution */
  imBinFileRead(handle, &dword, 1, 4);
  float xres = (float)dword / 100.0f;

  /* read the y resolution */
  imBinFileRead(handle, &dword, 1, 4);
  float yres = (float)dword / 100.0f;

  if (xres && yres)
  {
    imAttribTable* attrib_table = AttribTable();
    attrib_table->Set("XResolution", IM_FLOAT, 1, &xres);
    attrib_table->Set("YResolution", IM_FLOAT, 1, &yres);
    attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC");
  }

  if (this->bpp <= 8)
  {
    /* reads the number of colors used */
    imBinFileRead(handle, &dword, 1, 4);

    /* updates the palette_count based on the number of colors used */
    if (dword != 0 && dword < (unsigned int)this->palette_count)
      this->palette_count = dword;

    /* jump 4 bytes (important colors) */
    imBinFileSeekOffset(handle, 4);
  }
  else
  {
    /* jump 8 bytes (used colors, important colors) */
    imBinFileSeekOffset(handle, 8);
  }

  if (imBinFileError(handle))
    return IM_ERR_ACCESS;

  if (this->bpp <= 8)
    return ReadPalette();

  if (this->bpp == 16 || this->bpp == 32)
  {
    if (this->comp_type == BMP_BITFIELDS)
    {
      unsigned int Mask;
      unsigned int PalMask[3];

      imBinFileRead(handle, PalMask, 3, 4);
      if (imBinFileError(handle))
        return IM_ERR_ACCESS;

      this->roff = 0;
      this->rmask = Mask = PalMask[0];
      while (!(Mask & 0x01) && (Mask != 0))
        {Mask >>= 1; this->roff++;}

      this->goff = 0;
      this->gmask = Mask = PalMask[1];
      while (!(Mask & 0x01) && (Mask != 0))
        {Mask >>= 1; this->goff++;}

      this->boff = 0;
      this->bmask = Mask = PalMask[2];
      while (!(Mask & 0x01) && (Mask != 0))
        {Mask >>= 1; this->boff++;}
    }
    else
    {
      if (this->bpp == 16)
Exemplo n.º 8
0
   bool ReadGifData(){

      enum{                   //gif-extension flags
         GE_TRANSPARENT = 1,
         GE_USER_INPUT = 2,
                              //2-4: disposal method
      };
      struct{                 //graphic control extension
         byte blocksize;      //block size: 4 bytes
         byte flags;
         word delay;          //delay time (1/100 seconds)
         byte transparent;    //transparent color index
      } gif_extension;
      bool gfx_extension_found = false;

      //frame_disposal = DISPOSAL_UNDEFINED;

                              //now we have 3 possibilities:
                              // a) get and extension block (blocks with additional information)
                              // b) get an image separator (introductor to an image)
                              // c) get the trailer char (end of gif file)
      while(!fl->IsEof()){
         byte code;
         if(!fl->ReadByte(code))
            return false;
         switch(code){
         case 0x21:
            {
                              //*a* extension block - only in Gif89a or newer
               byte subcode;
               fl->ReadByte(subcode);
               switch(subcode){
               case 0xf9:
                  {
                                 //graphic control extension
                     fl->Read(&gif_extension, 5);
                     assert(gif_extension.blocksize==4);
                     gfx_extension_found = true;
                     if(transparent){
                              //restore previous transparent color to non-transparent
                        assert(transparent_index!=0x100);
                        S_rgb *pal = use_local_palette ? local_palette : global_palette;
                        pal[transparent_index].a = 0xff;
                     }
                     transparent = (gif_extension.flags&GE_TRANSPARENT);
                     transparent_index = transparent ? gif_extension.transparent : 0x100;

                              //process disposal
                     if(curr_frame==-1)
                        MemSet(pic_buffer, background, size_x*size_y);
                     else
                     if(frame_disposal==DISPOSAL_RESTORE_BGND){
                        byte *d = pic_buffer + decoded_rect.y*size_x + decoded_rect.x;
                        for(int y=0; y<decoded_rect.sy; y++){
                           MemSet(d, background, decoded_rect.sx);
                           d += size_x;
                        }
                     }

                     frame_disposal = (E_DISPOSAL)(gif_extension.flags>>2);

#ifdef DEBUG_FIXED_ANIM_TIME
                     frame_persist_time = gif_extension.delay ? DEBUG_FIXED_ANIM_TIME : 0;
#else
                     frame_persist_time = gif_extension.delay;
                     if(!frame_persist_time)
                        frame_persist_time = 10;
                     frame_persist_time *= 10;
#endif

                                 //block terminator (always 0)
                     byte term;
                     fl->ReadByte(term);
                  }
                  break;

               case 0xfe:        //comment extension
               case 0x01:        //plaintext extension
               case 0xff:        //application extension
               default:          //unknown extension
                                 //read (and ignore) data sub-blocks
                  while(true){
                     byte block_length;
                     if(!fl->ReadByte(block_length))
                        return false;
                     if(!block_length)
                        break;
#ifdef _DEBUG_
                     byte *bp = new byte[block_length];
                     fl->Read(bp, block_length);
                     delete[] bp;
#else
                     if(!fl->Seek(fl->Tell() + block_length))
                        return false;
#endif
                  }
                  break;
               }
            }
            break;

         case 0x2c:
            {
                              //*b* image (0x2c image separator)
               enum{
                              //0-2: size of local color table
                              //3-4: (reserved)
                  FLG_SORT = 0x20,
                  FLG_INTERLACE = 0x40,
                  FLG_LOCAL_COLOR = 0x80,
               };

                              //read image descriptor
               struct{
                  word xpos;
                  word ypos;
                  word width;
                  word height;
                  byte flags;
               } gif_id;
               fl->Read(&gif_id, 9);
               bool local_colormap = (gif_id.flags&FLG_LOCAL_COLOR);

#if 0
               /*
               if(gfx_extension_found){
                  nextimage->transparent = (gifgce.flags&0x01) ? gifgce.transparent : -1;
                  nextimage->transparency = (gifgce.flags&0x1c)>1 ? 1 : 0;
                  nextimage->delay = gifgce.delay*10;
               }
               */
#endif
               decoded_rect = S_rect(gif_id.xpos, gif_id.ypos, gif_id.width, gif_id.height);

               if(local_colormap){
                              //read color map (if descriptor says so)
                  int num_colors = 2 << (gif_id.flags&7);
                  ReadPalette(local_palette, num_colors);
                  use_local_palette = true;
               }else{
                              //otherwise use global
                  use_local_palette = false;
               }
               if(transparent// && frame_disposal==DISPOSAL_RESTORE_BGND
                  ){
                  S_rgb *pal = use_local_palette ? local_palette : global_palette;
                  pal[transparent_index].a = 0;
               }

               interlaced = (gif_id.flags&FLG_INTERLACE);
                              //1st byte of img block (codesize)
               fl->ReadByte(init_code_size);
               assert(init_code_size>0 && init_code_size<=8);
               //if(init_code_size>8)
                  //init_code_size = 8;

               BeginLZWDecode();

               if(interlaced){
                  decoded_img.Resize(decoded_rect.sx*decoded_rect.sy, background);
                  
                  DecodeInterlaced();
               }
               curr_line = 0;
               ++curr_frame;
               gfx_extension_found = false;
               return true;
            }
            break;

         case 0x3b:
                              //*c* trailer: end of gif info
                              //standard end
            if(!IsAnimated())
               return true;
            fl->Seek(beg_anim_file_offset);
            curr_frame = -1;
            break;
         }
      }
      return true;
   }
Exemplo n.º 9
0
int imFileFormatRAS::ReadImageInfo(int index)
{
  (void)index;
  unsigned int dword_value;

  this->file_data_type = IM_BYTE;

  /* reads the image width */
  imBinFileRead(handle, &dword_value, 1, 4);
  this->width = (int)dword_value;

  /* reads the image height */
  imBinFileRead(handle, &dword_value, 1, 4);
  this->height = (int)dword_value;

  /* reads the number of bits per pixel */
  imBinFileRead(handle, &this->bpp, 1, 4);

  if (imBinFileError(handle))
    return IM_ERR_ACCESS;

  // sanity check
  if (this->bpp != 1 && this->bpp != 8 && 
      this->bpp != 24 && this->bpp != 32)
    return IM_ERR_DATA;

  if (this->bpp > 8)
  {
    this->file_color_mode = IM_RGB;
    this->file_color_mode |= IM_PACKED;

    if (this->bpp == 32)
      this->file_color_mode |= IM_ALPHA;
  }
  else
  {
    this->file_color_mode = IM_MAP;

    if (this->bpp == 1)
    {
      this->convert_bpp = 1;
      this->palette_count = 2;
    }
  }

  this->file_color_mode |= IM_TOPDOWN;

  this->line_raw_size = imFileLineSizeAligned(this->width, this->bpp, 2);
  this->line_buffer_extra = 2; // room enough for padding

  /* jump 8 bytes (Length+Compression) */
  imBinFileSeekOffset(handle, 8);

  /* reads the palette information */
  imBinFileRead(handle, &this->map_type, 1, 4);

  /* reads the palette size */
  imBinFileRead(handle, &dword_value, 1, 4);

  if (imBinFileError(handle))
    return IM_ERR_ACCESS;

  /* updates the pal_size based on the palette size */
  if (this->bpp <= 8 && this->map_type != RAS_NONE)
  {
    this->palette_count = dword_value / 3;
    return ReadPalette();
  }

  if (this->bpp <= 8 && this->map_type == RAS_NONE)
  {
    if (this->bpp == 1)
      this->file_color_mode = IM_BINARY;
    else
      this->file_color_mode = IM_GRAY;

    this->file_color_mode |= IM_TOPDOWN;
  }

  return IM_ERR_NONE;
}
Exemplo n.º 10
0
RageSurfaceUtils::OpenResult RageSurface_Load_GIF( const RString &sPath, RageSurface *&ret, bool bHeaderOnly, RString &error )
{
	unsigned char buf[256];
	int imageCount = 0;
	int imageNumber = 1;
	RageFile f;

	if( !f.Open( sPath ) )
	{
		error = f.GetError();
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}
	
	if( !ReadOK(f, buf, 6) )
	{
		error = "error reading magic number";
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}
	if( strncmp((char *) buf, "GIF", 3) != 0 )
	{
		error = "not a GIF file";
		return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT;
	}

	{
		char version[4];
		strncpy(version, (char *) buf + 3, 3);
		version[3] = '\0';

		if( (strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0) )
		{
			error = "bad version number, not '87a' or '89a'";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
	}

	if( !ReadOK(f, buf, 7) )
	{
		error = "failed to read screen descriptor";
		return RageSurfaceUtils::OPEN_FATAL_ERROR;
	}

	RageSurfaceColor GlobalColorMap[MAXCOLORMAPSIZE];
	unsigned int GlobalBitPixel = 0;

	GlobalBitPixel = 2 << (buf[4] & 0x07);

	if( BitSet(buf[4], LOCALCOLORMAP) )
	{
		/* Global Colormap */
		if( !ReadPalette(f, GlobalBitPixel, GlobalColorMap ) )
		{
			error = "error reading global colormap";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
	}

	int transparency = -1;

	while(1)
	{
		unsigned char type;
		if( !ReadOK(f, &type, 1) )
		{
			error = "EOF / read error on image data";
			return RageSurfaceUtils::OPEN_FATAL_ERROR;
		}
		switch( type )
		{
		case ';':
		{
			/* GIF terminator */
			if( imageCount < imageNumber )
			{
				error = ssprintf( "only %d image%s found in file",
					imageCount, imageCount > 1 ? "s" : "");
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}
		}

		case '!':
		{
			/* Extension */
			unsigned char label;
			if( !ReadOK(f, &label, 1) )
			{
				error = "EOF / read error on extention function code";
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}

			switch( label )
			{
			case 0xf9:
				GetDataBlock( f, (unsigned char *) buf );
				if( (buf[0] & 0x1) != 0 )
					transparency  = buf[3];
			}

			while( GetDataBlock(f, (unsigned char *) buf) != 0 )
				;

			continue;
		}
		case ',':
		{
			++imageCount;

			if( !ReadOK(f, buf, 9) )
			{
				error = "couldn't read left/top/width/height";
				return RageSurfaceUtils::OPEN_FATAL_ERROR;
			}

			int bitPixel = 1 << ((buf[8] & 0x07) + 1);
			RageSurfaceColor LocalColorMap[MAXCOLORMAPSIZE];

			if( BitSet(buf[8], LOCALCOLORMAP) )
			{
				if( !ReadPalette(f, bitPixel, LocalColorMap) )
				{
					error = "error reading local colormap";
					return RageSurfaceUtils::OPEN_FATAL_ERROR;
				}
			} else {
				bitPixel = GlobalBitPixel;
				memcpy( LocalColorMap, GlobalColorMap, sizeof(LocalColorMap) );
			}

			ret = ReadImage( f, LM_to_uint(buf[4], buf[5]), LM_to_uint(buf[6], buf[7]),
					LocalColorMap, BitSet(buf[8], INTERLACE),
					imageCount != imageNumber );

			if( !ret )
				continue;

			if( transparency != -1 )
				ret->format->palette->colors[ transparency ].a = 0;

			return RageSurfaceUtils::OPEN_OK;
		}
		default: continue; /* Not a valid start character */
		}
	}

	return RageSurfaceUtils::OPEN_FATAL_ERROR;
}