static int GetDataBlock (MG_RWops *area, unsigned char *buf) { unsigned char count; if (!ReadOK(area, &count, 1)) return 0; ZeroDataBlock = (count == 0); if ((count != 0) && (!ReadOK(area, buf, count))) return 0; return count; }
static bool ReadPalette( RageFile &f, int number, RageSurfaceColor buffer[MAXCOLORMAPSIZE] ) { for( int i = 0; i < number; ++i ) { if( !ReadOK(f, &buffer[i].r, sizeof(buffer[i].r)) ) return false; if( !ReadOK(f, &buffer[i].g, sizeof(buffer[i].g)) ) return false; if( !ReadOK(f, &buffer[i].b, sizeof(buffer[i].b)) ) return false; buffer[i].a = 0xFF; } return true; }
bool LWZState::Init( RageFile &f ) { unsigned char input_code_size; /* code size: */ if( !ReadOK(f, &input_code_size, 1) ) { // RWSetMsg("EOF / read error on image data"); return false; } set_code_size = input_code_size; code_size = set_code_size + 1; clear_code = 1 << set_code_size; end_code = clear_code + 1; max_code_size = 2 * clear_code; max_code = clear_code + 2; m_Code.Init(); fresh = true; memset( table, 0, sizeof(table) ); for( int i = 0; i < clear_code; ++i ) table[1][i] = i; sp = stack; return true; }
static gboolean ReadColorMap (FILE *fd, gint number, CMap buffer, gint *format) { guchar rgb[3]; gint flag; gint i; flag = TRUE; for (i = 0; i < number; ++i) { if (! ReadOK (fd, rgb, sizeof (rgb))) return FALSE; buffer[CM_RED][i] = rgb[0]; buffer[CM_GREEN][i] = rgb[1]; buffer[CM_BLUE][i] = rgb[2]; flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]); } *format = (flag) ? GRAYSCALE : COLOR; return TRUE; }
static tsize_t TIFFReadRawStrip1(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size, const char* module) { TIFFDirectory *td = &tif->tif_dir; if (!isMapped(tif)) { if (!SeekOK(tif, td->td_stripoffset[strip])) { TIFFError(module, "%s: Seek error at scanline %lu, strip %lu", tif->tif_name, (u_long) tif->tif_row, (u_long) strip); return (-1); } if (!ReadOK(tif, buf, size)) { TIFFError(module, "%s: Read error at scanline %lu", tif->tif_name, (u_long) tif->tif_row); return (-1); } } else { if (td->td_stripoffset[strip] + size > tif->tif_size) { TIFFError(module, "%s: Seek error at scanline %lu, strip %lu", tif->tif_name, (u_long) tif->tif_row, (u_long) strip); return (-1); } memcpy(buf, tif->tif_base + td->td_stripoffset[strip], size); } return (size); }
static int ReadImageDesc (MG_RWops *area, IMAGEDESC* ImageDesc, GIFSCREEN* GifScreen) { unsigned char buf[16]; if (!ReadOK (area, buf, 9)) { _MG_PRINTF ("EX_CTRL>GIF89a: bad image size\n"); return -1; } ImageDesc->Top = LM_to_uint (buf[0], buf[1]); ImageDesc->Left = LM_to_uint (buf[2], buf[3]); ImageDesc->Width = LM_to_uint (buf[4], buf[5]); ImageDesc->Height = LM_to_uint (buf[6], buf[7]); ImageDesc->haveColorMap = BitSet (buf[8], LOCALCOLORMAP); ImageDesc->bitPixel = 1 << ((buf[8] & 0x07) + 1); ImageDesc->interlace = BitSet(buf[8], INTERLACE); if (ImageDesc->haveColorMap) { _MG_PRINTF ("EX_CTRL>GIF89a: have local colormap\n"); if (ReadColorMap (area, ImageDesc->bitPixel, ImageDesc->ColorMap) < 0) { _MG_PRINTF ("EX_CTRL>GIF89a: bad local colormap\n"); return -1; } } else { memcpy (ImageDesc->ColorMap, GifScreen->ColorMap, MAXCOLORMAPSIZE*sizeof (RGB)); } return 0; }
static int ReadColorMap(SDL_RWops *src, int number, unsigned char buffer[3][MAXCOLORMAPSIZE], int *gray) { int i; unsigned char rgb[3]; int flag; flag = TRUE; for (i = 0; i < number; ++i) { if (!ReadOK(src, rgb, sizeof(rgb))) { IMG_SetError("bad colormap"); return 1; } buffer[CM_RED][i] = rgb[0]; buffer[CM_GREEN][i] = rgb[1]; buffer[CM_BLUE][i] = rgb[2]; flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]); } #if 0 if (flag) *gray = (number == 2) ? PBM_TYPE : PGM_TYPE; else *gray = PPM_TYPE; #else *gray = 0; #endif return FALSE; }
get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) /* This version is for reading raw-word-format PPM files with any maxval */ { ppm_source_ptr source = (ppm_source_ptr) sinfo; register JSAMPROW ptr; register U_CHAR * bufferptr; register JSAMPLE *rescale = source->rescale; JDIMENSION col; if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) ERREXIT(cinfo, JERR_INPUT_EOF); ptr = source->pub.buffer[0]; bufferptr = source->iobuffer; for (col = cinfo->image_width; col > 0; col--) { register int temp; temp = UCH(*bufferptr++) << 8; temp |= UCH(*bufferptr++); *ptr++ = rescale[temp]; temp = UCH(*bufferptr++) << 8; temp |= UCH(*bufferptr++); *ptr++ = rescale[temp]; temp = UCH(*bufferptr++) << 8; temp |= UCH(*bufferptr++); *ptr++ = rescale[temp]; } return 1; }
int copyFaxFile(TIFF* tifin, TIFF* tifout) { uint32 row; uint16 badrun; int ok; tifin->tif_rawdatasize = TIFFGetFileSize(tifin); tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize); if (!ReadOK(tifin, tifin->tif_rawdata, tifin->tif_rawdatasize)) { TIFFError(tifin->tif_name, "%s: Read error at scanline 0"); return (0); } tifin->tif_rawcp = tifin->tif_rawdata; tifin->tif_rawcc = tifin->tif_rawdatasize; (*tifin->tif_setupdecode)(tifin); (*tifin->tif_predecode)(tifin, (tsample_t) 0); tifin->tif_row = 0; badfaxlines = 0; badfaxrun = 0; _TIFFmemset(refbuf, 0, sizeof (refbuf)); row = 0; badrun = 0; /* current run of bad lines */ while (tifin->tif_rawcc > 0) { ok = (*tifin->tif_decoderow)(tifin, rowbuf, sizeof (rowbuf), 0); if (!ok) { badfaxlines++; badrun++; /* regenerate line from previous good line */ _TIFFmemcpy(rowbuf, refbuf, sizeof (rowbuf)); } else { if (badrun > badfaxrun) badfaxrun = badrun; badrun = 0; _TIFFmemcpy(refbuf, rowbuf, sizeof (rowbuf)); } tifin->tif_row++; if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) { fprintf(stderr, "%s: Write error at row %ld.\n", tifout->tif_name, (long) row); break; } row++; if (stretch) { if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) { fprintf(stderr, "%s: Write error at row %ld.\n", tifout->tif_name, (long) row); break; } row++; } } if (badrun > badfaxrun) badfaxrun = badrun; _TIFFfree(tifin->tif_rawdata); return (row); }
static int ReadGIFGlobal (MG_RWops *area, GIFSCREEN* GifScreen) { unsigned char buf[9]; unsigned char version[4]; if (!ReadOK (area, buf, 6)) return -1; /* not gif image*/ if (strncmp((char *) buf, "GIF", 3) != 0) return -1; strncpy ((char*)version, (char *) buf + 3, 3); version [3] = '\0'; if (strcmp ((const char*)version, "87a") != 0 && strcmp ((const char*)version, "89a") != 0) { _MG_PRINTF ("EX_CTRL>GIF89a: GIF version number not 87a or 89a.\n"); return -1; /* image loading error*/ } GifScreen->Background = -1; GifScreen->transparent = -1; GifScreen->delayTime = -1; GifScreen->inputFlag = -1; GifScreen->disposal = 0; if (!ReadOK (area, buf, 7)) { _MG_PRINTF ("EX_CTRL>GIF89a: bad screen descriptor\n"); return -1; /* image loading error*/ } GifScreen->Width = LM_to_uint (buf[0], buf[1]); GifScreen->Height = LM_to_uint (buf[2], buf[3]); GifScreen->BitPixel = 2 << (buf[4] & 0x07); GifScreen->ColorResolution = (((buf[4] & 0x70) >> 3) + 1); GifScreen->Background = buf[5]; GifScreen->AspectRatio = buf[6]; if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ _MG_PRINTF ("EX_CTRL>GIF89a: have global colormap: %d\n", GifScreen->Background); if (ReadColorMap (area, GifScreen->BitPixel, GifScreen->ColorMap)) { _MG_PRINTF ("EX_CTRL>GIF89a: bad global colormap\n"); return -1; /* image loading error*/ } } return 0; }
static int GetDataBlock( RageFile &f, unsigned char *buf ) { unsigned char count; if( !ReadOK(f, &count, 1) ) { /* pm_message("error in getting DataBlock size" ); */ return -1; } if( count != 0 && !ReadOK(f, buf, count) ) { /* pm_message("error in reading DataBlock" ); */ return -1; } return count; }
static int GetDataBlock(SDL_RWops *src, unsigned char *buf) { unsigned char count; if (!ReadOK(src, &count, 1)) { dbgout("error in getting DataBlock size\n"); return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (!ReadOK(src, buf, count))) { dbgout("error in reading DataBlock\n"); return -1; } return count; }
static int GetDataBlock(FILE *fd, unsigned char *buf){ unsigned char count; if (! ReadOK(fd,&count,1)) { fprintf(stderr,"error in getting DataBlock size\n" ); return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (! ReadOK(fd, buf, count))) { fprintf(stderr,"error in reading DataBlock\n" ); return -1; } return count; }
get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) /* This version is for reading raw-byte-format files with maxval = MAXJSAMPLE. * In this case we just read right into the JSAMPLE buffer! * Note that same code works for PPM and PGM files. */ { ppm_source_ptr source = (ppm_source_ptr) sinfo; if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) ERREXIT(cinfo, JERR_INPUT_EOF); return 1; }
Node *Next(List *pList, Node *pNode) { if (!ReadOK(&pList->lock)) { FatalError("Next - Not allowed to read!"); return NULL; } if (pNode == NULL) return pList->pHead; else return pNode->pNext; }
static gint GetDataBlock (FILE *fd, guchar *buf) { guchar count; if (! ReadOK (fd, &count, 1)) { g_message ("Error in getting DataBlock size"); return -1; } ZeroDataBlock = count == 0; if ((count != 0) && (! ReadOK (fd, buf, count))) { g_message ("Error in reading DataBlock"); return -1; } return count; }
static int ReadColorMap(FILE *fd, int number, RGBQUAD *buffer){ int i; unsigned char rgb[3]; char *str; for (i = 0; i < number; ++i, buffer++) { if (! ReadOK(fd, rgb, sizeof(rgb))){ strcpy(str,"bad colormap"); pm_error(str); } buffer->rgbRed= rgb[0]; buffer->rgbGreen= rgb[1]; buffer->rgbBlue= rgb[2]; buffer->rgbReserved= 0; } return 0; }
static int ReadColorMap (MG_RWops *area, int number, RGB* ColorMap) { int i; unsigned char rgb[3]; for (i = 0; i < number; ++i) { if (!ReadOK (area, rgb, sizeof(rgb))) { return -1; } ColorMap [i].r = rgb[0]; ColorMap [i].g = rgb[1]; ColorMap [i].b = rgb[2]; } return 0; }
get_corr_row16 (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) /* This version is for reading raw-word-format maxval = MAXJSAMPLE, any endian */ { ppm_source_ptr source = (ppm_source_ptr) sinfo; register JSAMPROW16 ptr; register U_CHAR * bufferptr; JDIMENSION col; if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) ERREXIT(cinfo, JERR_INPUT_EOF); ptr = (JSAMPROW16)source->pub.buffer[0]; bufferptr = source->iobuffer; for (col = cinfo->image_width; col > 0; col--) { *ptr = UCH(*bufferptr++) << 8; *ptr++ |= UCH(*bufferptr++); } return 1; }
get_scaled_gray_row16 (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) /* This version is for reading raw-byte-format PGM files with any maxval */ { ppm_source_ptr source = (ppm_source_ptr) sinfo; register JSAMPROW16 ptr; register U_CHAR * bufferptr; register JSAMPLE16 *rescale = (JSAMPROW16)source->rescale; JDIMENSION col; if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width)) ERREXIT(cinfo, JERR_INPUT_EOF); ptr = (JSAMPROW16)source->pub.buffer[0]; bufferptr = source->iobuffer; for (col = cinfo->image_width; col > 0; col--) { *ptr++ = rescale[UCH(*bufferptr++)]; } return 1; }
/* * Fetch a contiguous directory item. */ static tsize_t TIFFFetchData(TIFF* tif, TIFFDirEntry* dir, char* cp) { int w = tiffDataWidth[dir->tdir_type]; tsize_t cc = dir->tdir_count * w; if (!isMapped(tif)) { if (!SeekOK(tif, dir->tdir_offset)) goto bad; if (!ReadOK(tif, cp, cc)) goto bad; } else { if (dir->tdir_offset + cc > tif->tif_size) goto bad; _TIFFmemcpy(cp, tif->tif_base + dir->tdir_offset, cc); } if (tif->tif_flags & TIFF_SWAB) { switch (dir->tdir_type) { case TIFF_SHORT: case TIFF_SSHORT: TIFFSwabArrayOfShort((uint16*) cp, dir->tdir_count); break; case TIFF_LONG: case TIFF_SLONG: case TIFF_FLOAT: TIFFSwabArrayOfLong((uint32*) cp, dir->tdir_count); break; case TIFF_RATIONAL: case TIFF_SRATIONAL: TIFFSwabArrayOfLong((uint32*) cp, 2*dir->tdir_count); break; case TIFF_DOUBLE: TIFFSwabArrayOfDouble((double*) cp, dir->tdir_count); break; } } return (cc); bad: TIFFError(tif->tif_name, "Error fetching data for field \"%s\"", _TIFFFieldWithTag(tif, dir->tdir_tag)->field_name); return ((tsize_t) 0); }
static void ReadImage(FILE *fd,unsigned char *data,int len, int height, RGBQUAD *cmap, int bpp, int interlace) { unsigned char c; int v; int xpos = 0, ypos=0, pass=0; unsigned char *scanline; char *str; if (!ReadOK(fd,&c,1)){ strcpy(str,"EOF / read error on image data"); pm_error(str); } if (LWZReadByte(fd,TRUE,c)<0){ strcpy(str,"error reading image"); pm_error(str); } if((scanline = (unsigned char*)malloc(len)) == NULL){ strcpy(str,"couldn't allocate space for image"); pm_error(str); } while(ypos < height && (v = LWZReadByte(fd,FALSE,c)) >= 0){ switch(bitCount){ case 1: if (v){ scanline[xpos>>3] |= 128 >> (xpos&7); } else{ scanline[xpos>>3] &= 0xff7f >> (xpos&7); } break; case 4: if (xpos&1){ scanline[xpos>>1] |= v&15; } else{
static tsize_t TIFFReadRawTile1(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size, const char* module) { TIFFDirectory *td = &tif->tif_dir; if (!isMapped(tif)) { if (!SeekOK(tif, td->td_stripoffset[tile])) { TIFFError(module, "%s: Seek error at row %ld, col %ld, tile %ld", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col, (long) tile); return ((tsize_t) -1); } if (!ReadOK(tif, buf, size)) { TIFFError(module, "%s: Read error at row %ld, col %ld", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col); return ((tsize_t) -1); } } else { if (td->td_stripoffset[tile] + size > tif->tif_size) { TIFFError(module, "%s: Seek error at row %ld, col %ld, tile %ld", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col, (long) tile); return ((tsize_t) -1); } memcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); } return (size); }
/* * Link the current directory into the * directory chain for the file. */ static int TIFFLinkDirectory(TIFF* tif) { static const char module[] = "TIFFLinkDirectory"; toff_t nextdir; toff_t diroff, off; tif->tif_diroff = (TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1; diroff = tif->tif_diroff; if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong(&diroff); #if SUBIFD_SUPPORT if (tif->tif_flags & TIFF_INSUBIFD) { (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET); if (!WriteOK(tif, &diroff, sizeof (diroff))) { TIFFError(module, "%s: Error writing SubIFD directory link", tif->tif_name); return (0); } /* * Advance to the next SubIFD or, if this is * the last one configured, revert back to the * normal directory linkage. */ if (--tif->tif_nsubifd) tif->tif_subifdoff += sizeof (diroff); else tif->tif_flags &= ~TIFF_INSUBIFD; return (1); } #endif if (tif->tif_header.tiff_diroff == 0) { /* * First directory, overwrite offset in header. */ tif->tif_header.tiff_diroff = tif->tif_diroff; #define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f)) (void) TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET); if (!WriteOK(tif, &diroff, sizeof (diroff))) { TIFFError(tif->tif_name, "Error writing TIFF header"); return (0); } return (1); } /* * Not the first directory, search to the last and append. */ nextdir = tif->tif_header.tiff_diroff; do { uint16 dircount; if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, sizeof (dircount))) { TIFFError(module, "Error fetching directory count"); return (0); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); (void) TIFFSeekFile(tif, dircount * sizeof (TIFFDirEntry), SEEK_CUR); if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { TIFFError(module, "Error fetching directory link"); return (0); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong(&nextdir); } while (nextdir != 0); off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); if (!WriteOK(tif, &diroff, sizeof (diroff))) { TIFFError(module, "Error writing directory link"); return (0); } return (1); }
int TIFFRewriteDirectory( TIFF *tif ) { static const char module[] = "TIFFRewriteDirectory"; /* We don't need to do anything special if it hasn't been written. */ if( tif->tif_diroff == 0 ) return TIFFWriteDirectory( tif ); /* ** Find and zero the pointer to this directory, so that TIFFLinkDirectory ** will cause it to be added after this directories current pre-link. */ /* Is it the first directory in the file? */ if (tif->tif_header.tiff_diroff == tif->tif_diroff) { tif->tif_header.tiff_diroff = 0; tif->tif_diroff = 0; #if defined(__hpux) && defined(__LP64__) #define HDROFF(f) ((toff_t)(unsigned long) &(((TIFFHeader*) 0)->f)) #else #define HDROFF(f) ((toff_t) &(((TIFFHeader*) 0)->f)) #endif TIFFSeekFile(tif, HDROFF(tiff_diroff), SEEK_SET); if (!WriteOK(tif, &(tif->tif_header.tiff_diroff), sizeof (tif->tif_diroff))) { TIFFError(tif->tif_name, "Error updating TIFF header"); return (0); } } else { toff_t nextdir, off; nextdir = tif->tif_header.tiff_diroff; do { uint16 dircount; if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, sizeof (dircount))) { TIFFError(module, "Error fetching directory count"); return (0); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&dircount); (void) TIFFSeekFile(tif, dircount * sizeof (TIFFDirEntry), SEEK_CUR); if (!ReadOK(tif, &nextdir, sizeof (nextdir))) { TIFFError(module, "Error fetching directory link"); return (0); } if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong(&nextdir); } while (nextdir != tif->tif_diroff && nextdir != 0); off = TIFFSeekFile(tif, 0, SEEK_CUR); /* get current offset */ (void) TIFFSeekFile(tif, off - (toff_t)sizeof(nextdir), SEEK_SET); tif->tif_diroff = 0; if (!WriteOK(tif, &(tif->tif_diroff), sizeof (nextdir))) { TIFFError(module, "Error writing directory link"); return (0); } } /* ** Now use TIFFWriteDirectory() normally. */ return TIFFWriteDirectory( tif ); }
TIFF* TIFFClientOpen( const char* name, const char* mode, thandle_t clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc ) { static const char module[] = "TIFFClientOpen"; TIFF *tif; int m; const char* cp; /* The following are configuration checks. They should be redundant, but should not * compile to any actual code in an optimised release build anyway. If any of them * fail, (makefile-based or other) configuration is not correct */ assert(sizeof(uint8)==1); assert(sizeof(int8)==1); assert(sizeof(uint16)==2); assert(sizeof(int16)==2); assert(sizeof(uint32)==4); assert(sizeof(int32)==4); assert(sizeof(uint64)==8); assert(sizeof(int64)==8); assert(sizeof(tmsize_t)==sizeof(void*)); { union{ uint8 a8[2]; uint16 a16; } n; n.a8[0]=1; n.a8[1]=0; #ifdef WORDS_BIGENDIAN assert(n.a16==256); #else assert(n.a16==1); #endif } m = _TIFFgetMode(mode, module); if (m == -1) goto bad2; tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1)); if (tif == NULL) { TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name); goto bad2; } _TIFFmemset(tif, 0, sizeof (*tif)); tif->tif_name = (char *)tif + sizeof (TIFF); strcpy(tif->tif_name, name); tif->tif_mode = m &~ (O_CREAT|O_TRUNC); tif->tif_curdir = (uint16) -1; /* non-existent directory */ tif->tif_curoff = 0; tif->tif_curstrip = (uint32) -1; /* invalid strip */ tif->tif_row = (uint32) -1; /* read/write pre-increment */ tif->tif_clientdata = clientdata; if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { TIFFErrorExt(clientdata, module, "One of the client procedures is NULL pointer."); goto bad2; } tif->tif_readproc = readproc; tif->tif_writeproc = writeproc; tif->tif_seekproc = seekproc; tif->tif_closeproc = closeproc; tif->tif_sizeproc = sizeproc; if (mapproc) tif->tif_mapproc = mapproc; else tif->tif_mapproc = _tiffDummyMapProc; if (unmapproc) tif->tif_unmapproc = unmapproc; else tif->tif_unmapproc = _tiffDummyUnmapProc; _TIFFSetDefaultCompressionState(tif); /* setup default state */ /* * Default is to return data MSB2LSB and enable the * use of memory-mapped files and strip chopping when * a file is opened read-only. */ tif->tif_flags = FILLORDER_MSB2LSB; if (m == O_RDONLY ) tif->tif_flags |= TIFF_MAPPED; #ifdef STRIPCHOP_DEFAULT if (m == O_RDONLY || m == O_RDWR) tif->tif_flags |= STRIPCHOP_DEFAULT; #endif /* * Process library-specific flags in the open mode string. * The following flags may be used to control intrinsic library * behaviour that may or may not be desirable (usually for * compatibility with some application that claims to support * TIFF but only supports some braindead idea of what the * vendor thinks TIFF is): * * 'l' use little-endian byte order for creating a file * 'b' use big-endian byte order for creating a file * 'L' read/write information using LSB2MSB bit order * 'B' read/write information using MSB2LSB bit order * 'H' read/write information using host bit order * 'M' enable use of memory-mapped files when supported * 'm' disable use of memory-mapped files * 'C' enable strip chopping support when reading * 'c' disable strip chopping support * 'h' read TIFF header only, do not load the first IFD * '4' ClassicTIFF for creating a file (default) * '8' BigTIFF for creating a file * * The use of the 'l' and 'b' flags is strongly discouraged. * These flags are provided solely because numerous vendors, * typically on the PC, do not correctly support TIFF; they * only support the Intel little-endian byte order. This * support is not configured by default because it supports * the violation of the TIFF spec that says that readers *MUST* * support both byte orders. It is strongly recommended that * you not use this feature except to deal with busted apps * that write invalid TIFF. And even in those cases you should * bang on the vendors to fix their software. * * The 'L', 'B', and 'H' flags are intended for applications * that can optimize operations on data by using a particular * bit order. By default the library returns data in MSB2LSB * bit order for compatibiltiy with older versions of this * library. Returning data in the bit order of the native cpu * makes the most sense but also requires applications to check * the value of the FillOrder tag; something they probably do * not do right now. * * The 'M' and 'm' flags are provided because some virtual memory * systems exhibit poor behaviour when large images are mapped. * These options permit clients to control the use of memory-mapped * files on a per-file basis. * * The 'C' and 'c' flags are provided because the library support * for chopping up large strips into multiple smaller strips is not * application-transparent and as such can cause problems. The 'c' * option permits applications that only want to look at the tags, * for example, to get the unadulterated TIFF tag information. */ for (cp = mode; *cp; cp++) switch (*cp) { case 'b': #ifndef WORDS_BIGENDIAN if (m&O_CREAT) tif->tif_flags |= TIFF_SWAB; #endif break; case 'l': #ifdef WORDS_BIGENDIAN if ((m&O_CREAT)) tif->tif_flags |= TIFF_SWAB; #endif break; case 'B': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | FILLORDER_MSB2LSB; break; case 'L': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | FILLORDER_LSB2MSB; break; case 'H': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | HOST_FILLORDER; break; case 'M': if (m == O_RDONLY) tif->tif_flags |= TIFF_MAPPED; break; case 'm': if (m == O_RDONLY) tif->tif_flags &= ~TIFF_MAPPED; break; case 'C': if (m == O_RDONLY) tif->tif_flags |= TIFF_STRIPCHOP; break; case 'c': if (m == O_RDONLY) tif->tif_flags &= ~TIFF_STRIPCHOP; break; case 'h': tif->tif_flags |= TIFF_HEADERONLY; break; case '8': if (m&O_CREAT) tif->tif_flags |= TIFF_BIGTIFF; break; } /* * Read in TIFF header. */ if ((m & O_TRUNC) || !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) { if (tif->tif_mode == O_RDONLY) { TIFFErrorExt(tif->tif_clientdata, name, "Cannot read TIFF header"); goto bad; } /* * Setup header and write. */ #ifdef WORDS_BIGENDIAN tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN; #else tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN; #endif if (!(tif->tif_flags&TIFF_BIGTIFF)) { tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC; tif->tif_header.classic.tiff_diroff = 0; if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&tif->tif_header.common.tiff_version); tif->tif_header_size = sizeof(TIFFHeaderClassic); } else { tif->tif_header.common.tiff_version = TIFF_VERSION_BIG; tif->tif_header.big.tiff_offsetsize = 8; tif->tif_header.big.tiff_unused = 0; tif->tif_header.big.tiff_diroff = 0; if (tif->tif_flags & TIFF_SWAB) { TIFFSwabShort(&tif->tif_header.common.tiff_version); TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); } tif->tif_header_size = sizeof (TIFFHeaderBig); } /* * The doc for "fopen" for some STD_C_LIBs says that if you * open a file for modify ("+"), then you must fseek (or * fflush?) between any freads and fwrites. This is not * necessary on most systems, but has been shown to be needed * on Solaris. */ TIFFSeekFile( tif, 0, SEEK_SET ); if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) { TIFFErrorExt(tif->tif_clientdata, name, "Error writing TIFF header"); goto bad; } /* * Setup the byte order handling. */ if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { #ifndef WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } else { #ifdef WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } /* * Setup default directory. */ if (!TIFFDefaultDirectory(tif)) goto bad; tif->tif_diroff = 0; tif->tif_dirlist = NULL; tif->tif_dirlistsize = 0; tif->tif_dirnumber = 0; return (tif); } /* * Setup the byte order handling. */ if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN && tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN #if MDI_SUPPORT && #if HOST_BIGENDIAN tif->tif_header.common.tiff_magic != MDI_BIGENDIAN #else tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN #endif ) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF or MDI file, bad magic number %d (0x%x)", #else ) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad magic number %d (0x%x)", #endif tif->tif_header.common.tiff_magic, tif->tif_header.common.tiff_magic); goto bad; } if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) { #ifndef WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } else { #ifdef WORDS_BIGENDIAN tif->tif_flags |= TIFF_SWAB; #endif } if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&tif->tif_header.common.tiff_version); if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&& (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad version number %d (0x%x)", tif->tif_header.common.tiff_version, tif->tif_header.common.tiff_version); goto bad; } if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC) { if (tif->tif_flags & TIFF_SWAB) TIFFSwabLong(&tif->tif_header.classic.tiff_diroff); tif->tif_header_size = sizeof(TIFFHeaderClassic); } else { if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic)))) { TIFFErrorExt(tif->tif_clientdata, name, "Cannot read TIFF header"); goto bad; } if (tif->tif_flags & TIFF_SWAB) { TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize); TIFFSwabLong8(&tif->tif_header.big.tiff_diroff); } if (tif->tif_header.big.tiff_offsetsize != 8) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)", tif->tif_header.big.tiff_offsetsize, tif->tif_header.big.tiff_offsetsize); goto bad; } if (tif->tif_header.big.tiff_unused != 0) { TIFFErrorExt(tif->tif_clientdata, name, "Not a TIFF file, bad BigTIFF unused %d (0x%x)", tif->tif_header.big.tiff_unused, tif->tif_header.big.tiff_unused); goto bad; } tif->tif_header_size = sizeof(TIFFHeaderBig); tif->tif_flags |= TIFF_BIGTIFF; } tif->tif_flags |= TIFF_MYBUFFER; tif->tif_rawcp = tif->tif_rawdata = 0; tif->tif_rawdatasize = 0; tif->tif_rawdataoff = 0; tif->tif_rawdataloaded = 0; switch (mode[0]) { case 'r': if (!(tif->tif_flags&TIFF_BIGTIFF)) tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff; else tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff; /* * Try to use a memory-mapped file if the client * has not explicitly suppressed usage with the * 'm' flag in the open mode (see above). */ if (tif->tif_flags & TIFF_MAPPED) { toff_t n; if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n)) { tif->tif_size=(tmsize_t)n; assert((toff_t)tif->tif_size==n); } else tif->tif_flags &= ~TIFF_MAPPED; } /* * Sometimes we do not want to read the first directory (for example, * it may be broken) and want to proceed to other directories. I this * case we use the TIFF_HEADERONLY flag to open file and return * immediately after reading TIFF header. */ if (tif->tif_flags & TIFF_HEADERONLY) return (tif); /* * Setup initial directory. */ if (TIFFReadDirectory(tif)) { tif->tif_rawcc = (tmsize_t)-1; tif->tif_flags |= TIFF_BUFFERSETUP; return (tif); } break; case 'a': /* * New directories are automatically append * to the end of the directory chain when they * are written out (see TIFFWriteDirectory). */ if (!TIFFDefaultDirectory(tif)) goto bad; return (tif); } bad: tif->tif_mode = O_RDONLY; /* XXX avoid flush */ TIFFCleanup(tif); bad2: return ((TIFF*)0); }
static SDL_Surface* ReadImage(SDL_RWops * src, int len, int height, int cmapSize, unsigned char cmap[3][MAXCOLORMAPSIZE], int gray, int interlace, int ignore) { SDL_Surface*image; unsigned char c; int i, v; int xpos = 0, ypos = 0, pass = 0; /* ** Initialize the compression routines */ if (!ReadOK(src, &c, 1)) { IMG_SetError("EOF / read error on image data"); return NULL; } if (LWZReadByte(src, TRUE, c) < 0) { IMG_SetError("error reading image"); return NULL; } /* ** If this is an "uninteresting picture" ignore it. */ if (ignore) { while (LWZReadByte(src, FALSE, c) >= 0) ; return NULL; } image = ImageNewCmap(len, height, cmapSize); for (i = 0; i < cmapSize; i++) ImageSetCmap(image, i, cmap[CM_RED][i], cmap[CM_GREEN][i], cmap[CM_BLUE][i]); while ((v = LWZReadByte(src, FALSE, c)) >= 0) { ((Uint8 *)image->pixels)[xpos + ypos * image->pitch] = v; ++xpos; if (xpos == len) { xpos = 0; if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if (ypos >= height) { ++pass; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: goto fini; } } } else { ++ypos; } } if (ypos >= height) break; } fini: return image; }
/* TODO: (Chase) dump frames into frameset instead of combining into one frame */ int IMG_LoadGIF_RW(SDL_RWops *src, IMG_File* dst) { int start; unsigned char buf[16]; unsigned char c; unsigned char localColorMap[3][MAXCOLORMAPSIZE]; int grayScale; int useGlobalColormap; int bitPixel; int imageCount = 0; char version[4]; int imageNumber = 1; /*<-- I believe this is what we want to control in order to change what frame to grab*/ int successCount = 0; int w = 0; int i = 0; Uint32 color = 0; SDL_Surface*image = NULL; SDL_Surface*nextImage = NULL; GifFrame frame; GifFrame* frames; if ( src == NULL ) { return 0; } start = SDL_RWtell(src); if (!ReadOK(src, buf, 6)) { IMG_SetError("error reading magic number"); goto done; } if (strncmp((char *) buf, "GIF", 3) != 0) { IMG_SetError("not a GIF file"); goto done; } strncpy(version, (char *) buf + 3, 3); version[3] = '\0'; if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { IMG_SetError("bad version number, not '87a' or '89a'"); goto done; } frame.transparent = -1; frame.delayMs = -1; frame.inputFlag = -1; frame.disposal = 0; if (!ReadOK(src, buf, 7)) { IMG_SetError("failed to read screen descriptor"); goto done; } GifScreen.Width = LM_to_uint(buf[0], buf[1]); GifScreen.Height = LM_to_uint(buf[2], buf[3]); GifScreen.BitPixel = 2 << (buf[4] & 0x07); GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1); GifScreen.Background = buf[5]; GifScreen.AspectRatio = buf[6]; if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap, &GifScreen.GrayScale)) { IMG_SetError("error reading global colormap"); goto done; } } dbgout("GLOBAL BG COLOR: Index:%i RGB:%i,%i,%i\n", GifScreen.Background, GifScreen.ColorMap[CM_RED][GifScreen.Background], GifScreen.ColorMap[CM_GREEN][GifScreen.Background], GifScreen.ColorMap[CM_BLUE][GifScreen.Background]); frames = (GifFrame*)malloc(sizeof(GifFrame)); if (!frames) { IMG_SetError("Malloc Failed"); goto done; } do { /* This loop goes through and reads every image and sends its data to ReadImage, if its the one we want (index 1) it'll output SDL_Surface*/ /* What this SHOULD do... METHOD 1 (Lazy): Read every image, output an SDL_Surface into a vector After loop, count vector images, make a new image which has a w equal to the vector.size() * image width Render each image from the vector onto the new image, each one with an x offset of image width * index Free all surfaces in the vector, return the new combined one. METHOD 2 (hardcore): Read every image, count the number of images we get. Create a surface with a w equal to count * width Go back and read every images data, writing their pixels, leftmost to images x * index GENERAL PROBLEM: We have no delay info. We'd have to manually set the frame delay... However, this isn't a problem. =3 Looks like we can have local layer color maps.. of course being able to do this in imageready is a whole other issue. But as far as we know.. maybe? */ if (!ReadOK(src, &c, 1)) { IMG_SetError("EOF / read error on image data"); goto done; } else dbgout("%c", c); if (c == ';') { /* GIF terminator -0x3b */ /*if (imageCount < imageNumber) { IMG_SetError("only %d image%s found in file", imageCount, imageCount > 1 ? "s" : ""); goto done; }*/ break; } if (c == '!') { /* Extension 0x21 */ if (!ReadOK(src, &c, 1)) { IMG_SetError("EOF / read error on extention function code"); goto done; } DoExtension(&frame, src, c); continue; } if (c != ',') { /* Image seperator - 0x2c */ continue; } ++imageCount; if (!ReadOK(src, buf, 9)) { IMG_SetError("couldn't read left/top/width/height"); goto done; } /* Offset Length Contents 0 1 byte Image Separator (0x2c) 1 2 bytes Image Left Position 3 2 bytes Image Top Position 5 2 bytes Image Width 7 2 bytes Image Height 8 1 byte bit 0: Local Color Table Flag (LCTF) bit 1: Interlace Flag bit 2: Sort Flag bit 2..3: Reserved bit 4..7: Size of Local Color Table: 2^(1+n) ? bytes Local Color Table(0..255 x 3 bytes) if LCTF is one 1 byte LZW Minimum Code Size [ // Blocks 1 byte Block Size (s) œSx (s)bytes Image Data ]* 1 byte Block Terminator(0x00) */ useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP); frame.x = LM_to_uint(buf[0], buf[1]); frame.y = LM_to_uint(buf[2], buf[3]); dbgout("X:%i, Y:%i\n", frame.x, frame.y); bitPixel = 1 << ((buf[8] & 0x07) + 1); dbgout("Checkpoint\n"); if (!useGlobalColormap) { if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) { IMG_SetError("error reading local colormap"); goto done; } image = ReadImage(src, LM_to_uint(buf[4], buf[5]), LM_to_uint(buf[6], buf[7]), bitPixel, localColorMap, grayScale, BitSet(buf[8], INTERLACE), 0); if (image) color = SDL_MapRGB(image->format, localColorMap[CM_RED][frame.transparent], localColorMap[CM_GREEN][frame.transparent], localColorMap[CM_BLUE][frame.transparent]); } else { image = ReadImage(src, LM_to_uint(buf[4], buf[5]), LM_to_uint(buf[6], buf[7]), GifScreen.BitPixel, GifScreen.ColorMap, GifScreen.GrayScale, BitSet(buf[8], INTERLACE), 0); if (image) color = SDL_MapRGB(image->format, GifScreen.ColorMap[CM_RED][frame.transparent], GifScreen.ColorMap[CM_GREEN][frame.transparent], GifScreen.ColorMap[CM_BLUE][frame.transparent]); } dbgout("Image: %p\n", image); if (image) { ++successCount; /*image = convertTo32bit(image); */ /* transform to a 32 bit surface because I HATE palettes*/ dbgout("Converted Image: %ix%i [%p]\n", image->w, image->h, image); if (image) { if ( frame.transparent >= 0 ) { SDL_SetColorKey(image, SDL_SRCCOLORKEY, frame.transparent); } /*if ( frame.transparent >= 0 ) { SDL_SetColorKey(image, SDL_SRCCOLORKEY, color); Uint8 r, g, b; SDL_GetRGB(color, image->format, &r, &g, &b); dbgout("Local Transparency: %i,%i,%i\n", r, g, b); }*/ /*Reallocate room for another image in the list*/ frames = (GifFrame*)realloc(frames, successCount * sizeof(GifFrame)); if (!frames) { /*realloc failed*/ IMG_SetError("Realloc Failed"); goto done; } frame.surf = image; /* Copy the current state of the GifFrame before the next read loop */ frames[successCount-1] = frame; /*int i = 0; while (i < successCount) { dbgout("Frames[%i]: %p\n", i, frames[i]); i++; }*/ image = NULL; } } } while (1); /*let the above ... goto's... handle it*/ SDL_Frame* framesArray; if (successCount > 0) { dbgout("Mallocing Frames %i\n", successCount);fflush(stdout); framesArray = IMG_MallocFrames(successCount); i = 0; //first frame image = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, GifScreen.Height, 32, RMASK, GMASK, BMASK, 0); color = SDL_MapRGB(image->format, GifScreen.ColorMap[CM_RED][frames[0].transparent], GifScreen.ColorMap[CM_GREEN][frames[0].transparent], GifScreen.ColorMap[CM_BLUE][frames[0].transparent]); Uint8 r, g, b; SDL_GetRGB(color, image->format, &r, &g, &b); dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout); if (color != 0) /* Ignore 0,0,0 as the transparent color */ { SDL_FillRect(image, NULL, color); SDL_SetColorKey(image, SDL_SRCCOLORKEY, color); /* use the first frames trans color */ } while (i < successCount) /* render our surfs and clear */ { if (image) { dbgout("Dimensions: %ix%i: %p\n", image->w, image->h, image);fflush(stdout); w = 0; SDL_Rect r2, r3; dbgout("Adding Frames[%i]: %p Disposal:%i TransIndex: %i Delay: %i Input:%i\n", i, frames[i].surf, frames[i].disposal, frames[i].transparent, frames[i].delayMs, frames[i].inputFlag); fflush(stdout); /* Print out the overlay at its offset coordinates */ r2.x = frames[i].x; r2.y = frames[i].y; r2.w = frames[i].surf->w; r2.h = frames[i].surf->h; dbgout("Drawing at: %i,%i\n", r2.x, r2.y);fflush(stdout); if (SDL_BlitSurface(frames[i].surf, NULL, image, &r2)) { /*something bad happened but ignore it for now. */ dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout); } dbgout("Setting Crap\n");fflush(stdout); //add image to our frames list framesArray[i].surf = image; framesArray[i].delay = frames[i].delayMs * 10; //HACK: All observed gifs have a delay of say.. 7, which means 70ms. framesArray[i].key = NULL; dbgout("i+1 crap\n");fflush(stdout); /*what to do in frame[i+1] before rendering*/ if (i + 1 < successCount) { //create next frame so we can do something to it nextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, GifScreen.Height, 32, RMASK, GMASK, BMASK, 0); color = SDL_MapRGB(nextImage->format, GifScreen.ColorMap[CM_RED][frames[0].transparent], GifScreen.ColorMap[CM_GREEN][frames[0].transparent], GifScreen.ColorMap[CM_BLUE][frames[0].transparent]); Uint8 r, g, b; SDL_GetRGB(color, nextImage->format, &r, &g, &b); dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout); if (color != 0) /* Ignore 0,0,0 as the transparent color */ { SDL_FillRect(nextImage, NULL, color); SDL_SetColorKey(nextImage, SDL_SRCCOLORKEY, color); /* use the first frames trans color */ } dbgout("Disposal crap\n");fflush(stdout); switch (frames[i].disposal) { case DISPOSAL_PREVIOUSFRAME: /* 04h - Overwrite graphic with previous graphic */ dbgout("Doing previous frame\n");fflush(stdout); r2.x = 0; r2.y = 0; r2.w = GifScreen.Width; r2.h = GifScreen.Height; SDL_BlitSurface(frames[0].surf, NULL, nextImage, &r2); //Since I'm lazy, and haven't seen many gifs use this, it'll just render the original frame break; case DISPOSAL_UNSPECIFIED: /* DISPOSAL_UNSPECIFIED 00h - Let the viewer decide */ /*Drop down to donotdispose */ case DISPOSAL_DONOTDISPOSE: /* 01h - Leave graphic there */ dbgout("Doing nondispose\n");fflush(stdout); /*render a copy of the previous i-1 into i */ r2.w = GifScreen.Width; r2.h = GifScreen.Height; r2.x = 0; r2.y = 0; /* r3 = src, r2 = dst */ r3.w = GifScreen.Width; r3.h = GifScreen.Height; r3.x = 0; r3.y = 0; dbgout("r3:(%i,%i)%ix%i r2:(%i,%i)%ix%i\n", r3.x, r3.y, r3.w, r3.h, r2.x, r2.y, r2.w, r2.h);fflush(stdout); if (SDL_BlitSurface(image, &r3, nextImage, &r2)) { dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout); } break; default: /* This'll default to DISPOSAL_BGCOLORWIPE 02h - Overwrite graphic with background color do nothing, next rect is empty already*/ dbgout("Doing default %i\n", frames[i].disposal);fflush(stdout); break; } image = nextImage; } } i++; } i = 0; while (i < successCount) { SDL_FreeSurface(frames[i].surf); i++; } free(frames); frames = NULL; } else { image = NULL; } done: if (frames) { /* We didn't complete successfully, handle any leaks */ i = 0; while (i < successCount) { SDL_FreeSurface(frames[i].surf); i++; } free(frames); /*if (image) { SDL_FreeSurface(image); image = NULL; }*/ } /*if ( image == NULL ) { SDL_RWseek(src, start, SEEK_SET); } */ if (successCount > 0) { dst->frames = framesArray; dst->count = successCount; dst->format = IMG_FORMAT_GIF; return 1; } return 0; //return IMG_SurfaceToFrameset(image, sdlFrames, sdlFrameCount); }
TIFF* TIFFClientOpen( const char* name, const char* mode, void* clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc, void* pdflib_opaque, TIFFmallocHandler malloc_h, TIFFreallocHandler realloc_h, TIFFfreeHandler free_h, TIFFErrorHandler error_h, TIFFErrorHandler warn_h ) { static const char module[] = "TIFFClientOpen"; TIFF pdftiff; TIFF *tif = &pdftiff; int m; int bigendian; const char* cp; (void) mapproc; (void) unmapproc; { union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; } m = _TIFFgetMode(mode, module); if (m == -1) goto bad2; /* PDFlib: preset tiff structure so that the first malloc works */ tif->pdflib_opaque = pdflib_opaque; tif->pdflib_malloc = malloc_h; tif->pdflib_realloc = realloc_h; tif->pdflib_free = free_h; tif->pdflib_error = error_h; tif->pdflib_warn = warn_h; tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + (tsize_t) strlen(name) + 1); if (tif == NULL) { _TIFFError(tif, module, "%s: Out of memory (TIFF structure)", name); goto bad2; } _TIFFmemset(tif, 0, sizeof (*tif)); /* PDFlib: add own mallochandling */ tif->pdflib_opaque = pdflib_opaque; tif->pdflib_malloc = malloc_h; tif->pdflib_realloc = realloc_h; tif->pdflib_free = free_h; tif->pdflib_error = error_h; tif->pdflib_warn = warn_h; tif->tif_name = (char *)tif + sizeof (TIFF); strcpy(tif->tif_name, name); tif->tif_mode = m &~ (O_CREAT|O_TRUNC); tif->tif_curdir = (tdir_t) -1; /* non-existent directory */ tif->tif_curoff = 0; tif->tif_curstrip = (tstrip_t) -1; /* invalid strip */ tif->tif_row = (uint32) -1; /* read/write pre-increment */ tif->tif_clientdata = clientdata; #ifdef PDFlib_NOT_USED if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) { _TIFFError(tif, module, "One of the client procedures is NULL pointer."); goto bad2; } #endif /* PDFLIB_TIFFWRITE_SUPPORT */ tif->tif_readproc = readproc; tif->tif_writeproc = writeproc; tif->tif_seekproc = seekproc; tif->tif_closeproc = closeproc; tif->tif_sizeproc = sizeproc; #ifdef HAVE_MMAP if (mapproc) tif->tif_mapproc = mapproc; else tif->tif_mapproc = _tiffDummyMapProc; if (unmapproc) tif->tif_unmapproc = unmapproc; else tif->tif_unmapproc = _tiffDummyUnmapProc; #endif _TIFFSetDefaultCompressionState(tif); /* setup default state */ /* * Default is to return data MSB2LSB and enable the * use of memory-mapped files and strip chopping when * a file is opened read-only. */ tif->tif_flags = FILLORDER_MSB2LSB; #ifdef HAVE_MMAP if (m == O_RDONLY ) tif->tif_flags |= TIFF_MAPPED; #endif #ifdef STRIPCHOP_DEFAULT if (m == O_RDONLY || m == O_RDWR) tif->tif_flags |= STRIPCHOP_DEFAULT; #endif /* * Process library-specific flags in the open mode string. * The following flags may be used to control intrinsic library * behaviour that may or may not be desirable (usually for * compatibility with some application that claims to support * TIFF but only supports some braindead idea of what the * vendor thinks TIFF is): * * 'l' use little-endian byte order for creating a file * 'b' use big-endian byte order for creating a file * 'L' read/write information using LSB2MSB bit order * 'B' read/write information using MSB2LSB bit order * 'H' read/write information using host bit order * 'M' enable use of memory-mapped files when supported * 'm' disable use of memory-mapped files * 'C' enable strip chopping support when reading * 'c' disable strip chopping support * 'h' read TIFF header only, do not load the first IFD * * The use of the 'l' and 'b' flags is strongly discouraged. * These flags are provided solely because numerous vendors, * typically on the PC, do not correctly support TIFF; they * only support the Intel little-endian byte order. This * support is not configured by default because it supports * the violation of the TIFF spec that says that readers *MUST* * support both byte orders. It is strongly recommended that * you not use this feature except to deal with busted apps * that write invalid TIFF. And even in those cases you should * bang on the vendors to fix their software. * * The 'L', 'B', and 'H' flags are intended for applications * that can optimize operations on data by using a particular * bit order. By default the library returns data in MSB2LSB * bit order for compatibiltiy with older versions of this * library. Returning data in the bit order of the native cpu * makes the most sense but also requires applications to check * the value of the FillOrder tag; something they probably do * not do right now. * * The 'M' and 'm' flags are provided because some virtual memory * systems exhibit poor behaviour when large images are mapped. * These options permit clients to control the use of memory-mapped * files on a per-file basis. * * The 'C' and 'c' flags are provided because the library support * for chopping up large strips into multiple smaller strips is not * application-transparent and as such can cause problems. The 'c' * option permits applications that only want to look at the tags, * for example, to get the unadulterated TIFF tag information. */ for (cp = mode; *cp; cp++) switch (*cp) { case 'b': if ((m&O_CREAT) && !bigendian) tif->tif_flags |= TIFF_SWAB; break; case 'l': if ((m&O_CREAT) && bigendian) tif->tif_flags |= TIFF_SWAB; break; case 'B': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | FILLORDER_MSB2LSB; break; case 'L': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | FILLORDER_LSB2MSB; break; #ifdef PDFlib_NOT_USED /* PDFlib GmbH */ case 'H': tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) | HOST_FILLORDER; break; #endif #ifdef HAVE_MMAP case 'M': if (m == O_RDONLY) tif->tif_flags |= TIFF_MAPPED; break; case 'm': if (m == O_RDONLY) tif->tif_flags &= ~TIFF_MAPPED; break; #endif case 'C': if (m == O_RDONLY) tif->tif_flags |= TIFF_STRIPCHOP; break; case 'c': if (m == O_RDONLY) tif->tif_flags &= ~TIFF_STRIPCHOP; break; case 'h': tif->tif_flags |= TIFF_HEADERONLY; break; } /* * Read in TIFF header. */ if (tif->tif_mode & O_TRUNC || !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { if (tif->tif_mode == O_RDONLY) { _TIFFError(tif, name, "Cannot read TIFF header"); goto bad; } /* * Setup header and write. */ tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN) : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN); tif->tif_header.tiff_version = TIFF_VERSION; if (tif->tif_flags & TIFF_SWAB) TIFFSwabShort(&tif->tif_header.tiff_version); tif->tif_header.tiff_diroff = 0; /* filled in later */ /* * The doc for "fopen" for some STD_C_LIBs says that if you * open a file for modify ("+"), then you must fseek (or * fflush?) between any freads and fwrites. This is not * necessary on most systems, but has been shown to be needed * on Solaris. */ TIFFSeekFile( tif, 0, SEEK_SET ); if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) { _TIFFError(tif, name, "Error writing TIFF header"); goto bad; } /* * Setup the byte order handling. */ TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); /* * Setup default directory. */ if (!TIFFDefaultDirectory(tif)) goto bad; tif->tif_diroff = 0; tif->tif_dirlist = NULL; tif->tif_dirnumber = 0; return (tif); } /* * Setup the byte order handling. */ if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN && tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) { _TIFFError(tif, name, "Not a TIFF file, bad magic number %d (0x%x)", tif->tif_header.tiff_magic, tif->tif_header.tiff_magic); goto bad; } TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian); /* * Swap header if required. */ if (tif->tif_flags & TIFF_SWAB) { TIFFSwabShort(&tif->tif_header.tiff_version); TIFFSwabLong(&tif->tif_header.tiff_diroff); } /* * Now check version (if needed, it's been byte-swapped). * Note that this isn't actually a version number, it's a * magic number that doesn't change (stupid). */ if (tif->tif_header.tiff_version == TIFF_BIGTIFF_VERSION) { _TIFFError(tif, name, "This is a BigTIFF file. This format not supported\n" "by this version of libtiff." ); goto bad; } if (tif->tif_header.tiff_version != TIFF_VERSION) { _TIFFError(tif, name, "Not a TIFF file, bad version number %d (0x%x)", tif->tif_header.tiff_version, tif->tif_header.tiff_version); goto bad; } tif->tif_flags |= TIFF_MYBUFFER; tif->tif_rawcp = tif->tif_rawdata = 0; tif->tif_rawdatasize = 0; /* * Sometimes we do not want to read the first directory (for example, * it may be broken) and want to proceed to other directories. I this * case we use the TIFF_HEADERONLY flag to open file and return * immediately after reading TIFF header. */ if (tif->tif_flags & TIFF_HEADERONLY) return (tif); /* * Setup initial directory. */ switch (mode[0]) { case 'r': tif->tif_nextdiroff = tif->tif_header.tiff_diroff; #ifdef HAVE_MMAP /* * Try to use a memory-mapped file if the client * has not explicitly suppressed usage with the * 'm' flag in the open mode (see above). */ if ((tif->tif_flags & TIFF_MAPPED) && !TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size)) tif->tif_flags &= ~TIFF_MAPPED; #endif if (TIFFReadDirectory(tif)) { tif->tif_rawcc = -1; tif->tif_flags |= TIFF_BUFFERSETUP; return (tif); } break; case 'a': /* * New directories are automatically append * to the end of the directory chain when they * are written out (see TIFFWriteDirectory). */ if (!TIFFDefaultDirectory(tif)) goto bad; return (tif); } bad: tif->tif_mode = O_RDONLY; /* XXX avoid flush */ TIFFCleanup(tif); bad2: return ((TIFF*)0); }
start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { tga_source_ptr source = (tga_source_ptr) sinfo; U_CHAR targaheader[18]; int idlen, cmaptype, subtype, flags, interlace_type, components; unsigned int width, height, maplen; boolean is_bottom_up; #define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \ (((unsigned int) UCH(targaheader[offset+1])) << 8)) if (! ReadOK(source->pub.input_file, targaheader, 18)) ERREXIT(cinfo, JERR_INPUT_EOF); /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */ if (targaheader[16] == 15) targaheader[16] = 16; idlen = UCH(targaheader[0]); cmaptype = UCH(targaheader[1]); subtype = UCH(targaheader[2]); maplen = GET_2B(5); width = GET_2B(12); height = GET_2B(14); source->pixel_size = UCH(targaheader[16]) >> 3; flags = UCH(targaheader[17]); /* Image Descriptor byte */ is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */ interlace_type = flags >> 6; /* bits 6/7 are interlace code */ if (cmaptype > 1 || /* cmaptype must be 0 or 1 */ source->pixel_size < 1 || source->pixel_size > 4 || (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */ interlace_type != 0) /* currently don't allow interlaced image */ ERREXIT(cinfo, JERR_TGA_BADPARMS); if (subtype > 8) { /* It's an RLE-coded file */ source->read_pixel = read_rle_pixel; source->block_count = source->dup_pixel_count = 0; subtype -= 8; } else { /* Non-RLE file */ source->read_pixel = read_non_rle_pixel; } /* Now should have subtype 1, 2, or 3 */ components = 3; /* until proven different */ cinfo->in_color_space = JCS_RGB; switch (subtype) { case 1: /* Colormapped image */ if (source->pixel_size == 1 && cmaptype == 1) source->get_pixel_rows = get_8bit_row; else ERREXIT(cinfo, JERR_TGA_BADPARMS); TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height); break; case 2: /* RGB image */ switch (source->pixel_size) { case 2: source->get_pixel_rows = get_16bit_row; break; case 3: source->get_pixel_rows = get_24bit_row; break; case 4: source->get_pixel_rows = get_32bit_row; break; default: ERREXIT(cinfo, JERR_TGA_BADPARMS); break; } TRACEMS2(cinfo, 1, JTRC_TGA, width, height); break; case 3: /* Grayscale image */ components = 1; cinfo->in_color_space = JCS_GRAYSCALE; if (source->pixel_size == 1) source->get_pixel_rows = get_8bit_gray_row; else ERREXIT(cinfo, JERR_TGA_BADPARMS); TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height); break; default: ERREXIT(cinfo, JERR_TGA_BADPARMS); break; } if (is_bottom_up) { /* Create a virtual array to buffer the upside-down image. */ source->whole_image = (*cinfo->mem->request_virt_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) width * components, (JDIMENSION) height, (JDIMENSION) 1); if (cinfo->progress != NULL) { cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; progress->total_extra_passes++; /* count file input as separate pass */ } /* source->pub.buffer will point to the virtual array. */ source->pub.buffer_height = 1; /* in case anyone looks at it */ source->pub.get_pixel_rows = preload_image; } else { /* Don't need a virtual array, but do need a one-row input buffer. */ source->whole_image = NULL; source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) width * components, (JDIMENSION) 1); source->pub.buffer_height = 1; source->pub.get_pixel_rows = source->get_pixel_rows; } while (idlen--) /* Throw away ID field */ (void) read_byte(source); if (maplen > 0) { if (maplen > 256 || GET_2B(3) != 0) ERREXIT(cinfo, JERR_TGA_BADCMAP); /* Allocate space to store the colormap */ source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3); /* and read it from the file */ read_colormap(source, (int) maplen, UCH(targaheader[7])); } else { if (cmaptype) /* but you promised a cmap! */ ERREXIT(cinfo, JERR_TGA_BADPARMS); source->colormap = NULL; } cinfo->input_components = components; cinfo->data_precision = 8; cinfo->image_width = width; cinfo->image_height = height; }