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; }
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; }
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; }
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; }
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; }
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; }
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)
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; }
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; }
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; }