static FLAC__StreamDecoderLengthStatus flac_length_music_cb ( const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { FLAC_music *data = (FLAC_music*)client_data; int pos = SDL_RWtell (data->rwops); int length = SDL_RWseek (data->rwops, 0, RW_SEEK_END); if (SDL_RWseek (data->rwops, pos, RW_SEEK_SET) != pos || length < 0) { /* there was an error attempting to return the stream to the original * position, or the length was invalid. */ return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; } else { *stream_length = (FLAC__uint64)length; return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; } }
/* See if an image is contained in a data source */ int IMG_isGIF(SDL_RWops *src) { Sint64 start; int is_GIF; char magic[6]; if ( !src ) return 0; start = SDL_RWtell(src); is_GIF = 0; if ( SDL_RWread(src, magic, sizeof(magic), 1) ) { if ( (SDL_strncmp(magic, "GIF", 3) == 0) && ((SDL_memcmp(magic + 3, "87a", 3) == 0) || (SDL_memcmp(magic + 3, "89a", 3) == 0)) ) { is_GIF = 1; } } SDL_RWseek(src, start, RW_SEEK_SET); return(is_GIF); }
MREADER *_mm_new_rwops_reader(SDL_RWops * rw) { int here; MRWOPSREADER* reader=(MRWOPSREADER*)_mm_malloc(sizeof(MRWOPSREADER)); if (reader) { reader->core.Eof =&_mm_RWopsReader_Eof; reader->core.Read=&_mm_RWopsReader_Read; reader->core.Get =&_mm_RWopsReader_Get; reader->core.Seek=&_mm_RWopsReader_Seek; reader->core.Tell=&_mm_RWopsReader_Tell; reader->rw=rw; /* RWops does not explicitly support an eof check, so we shall find the end manually - this requires seek support for the RWop */ here = SDL_RWtell(rw); reader->end = SDL_RWseek(rw, 0, SEEK_END); SDL_RWseek(rw, here, SEEK_SET); /* Move back */ } return (MREADER*)reader; }
static FLAC__bool flac_eof_music_cb( const FLAC__StreamDecoder *decoder, void *client_data ) { FLAC_music *data = (FLAC_music*)client_data; int pos = SDL_RWtell (data->rwops); int end = SDL_RWseek (data->rwops, 0, RW_SEEK_END); // was the original position equal to the end (a.k.a. the seek didn't move)? if (pos == end) { // must be EOF return true; } else { // not EOF, return to the original position SDL_RWseek (data->rwops, pos, RW_SEEK_SET); return false; } }
static int isLBM() { SDL_RWops* src = 0; int start; int is_LBM; Uint8 magic[4+4+4]; start = SDL_RWtell(src); is_LBM = 0; if ( SDL_RWread( src, magic, sizeof(magic), 1 ) ) { if ( !memcmp( magic, "FORM", 4 ) && ( !memcmp( magic + 8, "PBM ", 4 ) || !memcmp( magic + 8, "ILBM", 4 ) ) ) { is_LBM = 1; } } SDL_RWseek(src, start, SEEK_SET); return( is_LBM ); }
/* See if an image is contained in a data source */ int IMG_isPNG(SDL_RWops *src) { int start; int is_PNG; Uint8 magic[4]; if ( !src ) return 0; start = SDL_RWtell(src); is_PNG = 0; if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) { if ( magic[0] == 0x89 && magic[1] == 'P' && magic[2] == 'N' && magic[3] == 'G' ) { is_PNG = 1; } } SDL_RWseek(src, start, SEEK_SET); return(is_PNG); }
bool Serializer::writeScriptData() { int64_t fieldsPtr = SDL_RWtell(_rw); if (fieldsPtr < 0) return false; if (!SDL_WriteBE32(_rw, 0)) // 4 placeholder bytes for the actual number of fields return false; lua_getglobal(_L, "dgPersistence"); int32_t numFields = writeTable("dgPersistence"); if (numFields < 0) return false; if (SDL_RWseek(_rw, fieldsPtr, RW_SEEK_SET) < 0) // Restore file pointer to 4 placeholder bytes return false; if (!SDL_WriteBE32(_rw, numFields)) return false; if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end return false; return true; }
int IMG_isLBM( SDL_RWops *src ) { Sint64 start; int is_LBM; Uint8 magic[4+4+4]; if ( !src ) return 0; start = SDL_RWtell(src); is_LBM = 0; if ( SDL_RWread( src, magic, sizeof(magic), 1 ) ) { if ( !SDL_memcmp( magic, "FORM", 4 ) && ( !SDL_memcmp( magic + 8, "PBM ", 4 ) || !SDL_memcmp( magic + 8, "ILBM", 4 ) ) ) { is_LBM = 1; } } SDL_RWseek(src, start, RW_SEEK_SET); return( is_LBM ); }
//------------------------------------------------------------------------------------ // запись данных в VFS //------------------------------------------------------------------------------------ int vw_WriteIntoVFSfromFile(const char *SrcName, const char *DstName) { if (SrcName == 0) return -1; if (DstName == 0) return -1; // читаем данные файла в буфер SDL_RWops *Ftmp = SDL_RWFromFile(SrcName, "rb"); // Если файл не найден - выходим if (Ftmp == NULL) { fprintf(stderr, "Can't find file %s !!!\n", SrcName); return -1; } // получаем размер файла SDL_RWseek(Ftmp, 0, SEEK_END); int tmpLength = SDL_RWtell(Ftmp); SDL_RWseek(Ftmp, 0, SEEK_SET); // копируем все данные файла в массив BYTE *tmp = 0; tmp = new BYTE[tmpLength]; SDL_RWread(Ftmp, tmp, tmpLength, 1); SDL_RWclose(Ftmp); // запись в VFS if (0 != vw_WriteIntoVFSfromMemory(DstName, tmp, tmpLength)) { // какая-то ошибка, не можем записать в VFS delete [] tmp; tmp = 0; fprintf(stderr, "Can't write into VFS from memory %s !!!\n", DstName); return -1; } // Освобождаем память delete [] tmp; tmp = 0; return 0; }
/*--------------------------------------------------------------------------*/ int AG_isGIF( SDL_RWops* src ) { int isGIF = FALSE; if ( src ) { int start = SDL_RWtell( src ); char magic[6]; if ( SDL_RWread(src,magic,sizeof(magic),1) ) { if ( (strncmp(magic,"GIF",3) == 0) && ((memcmp(magic+3,"87a",3) == 0) || (memcmp(magic+3,"89a",3) == 0)) ) { isGIF = TRUE; } } SDL_RWseek( src, start, SEEK_SET ); } return isGIF; }
void Compression::DoCompression(const char *from, SDL_RWops *dst) { int lenght, lenghtComp; SDL_RWops *src = ged_SDL_RWFromFile(from, "rb"); if(!src) return; SDL_RWseek( src, 0, SEEK_END ); lenght = SDL_RWtell( src ); SDL_RWseek( src, 0, SEEK_SET ); U8 *in = new U8[lenght]; U8 *out = new U8[2*lenght/*lenght + lenght / 8 + 256*/]; //Solved crash when export Alittlecash_player.ged SDL_RWread(src, in, lenght, 1); lenghtComp = DoCompression(in, lenght, out, 2*lenght/*lenght + lenght / 8 + 256*/); if(lenghtComp < lenght) { SDL_WriteLE32( dst, lenght ); SDL_WriteLE32( dst, lenghtComp ); SDL_RWwrite(dst, out, lenghtComp, 1); } else { //No compression SDL_WriteLE32( dst, lenght ); SDL_WriteLE32( dst, lenght ); SDL_RWwrite(dst, in, lenght, 1); } delete [] in; delete [] out; SDL_RWclose(src); }
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw) { NativeMidiSong *song = NULL; char *extra; song = malloc(sizeof(NativeMidiSong)); if (!song) { return NULL; }; SDL_RWseek(rw, 0, SEEK_END); song->file_size = SDL_RWtell(rw); SDL_RWseek(rw, 0, SEEK_SET); song->filebuf = malloc(song->file_size); if (!song->filebuf) { free(song); return NULL; } SDL_RWread(rw, song->filebuf, song->file_size, 1); return song; }
/* See if an image is contained in a data source */ int IMG_isPCX(SDL_RWops *src) { int start; int is_PCX; const int ZSoft_Manufacturer = 10; const int PC_Paintbrush_Version = 5; const int PCX_RunLength_Encoding = 1; struct PCXheader pcxh; if ( !src ) return 0; start = SDL_RWtell(src); is_PCX = 0; if ( SDL_RWread(src, &pcxh, sizeof(pcxh), 1) == 1 ) { if ( (pcxh.Manufacturer == ZSoft_Manufacturer) && (pcxh.Version == PC_Paintbrush_Version) && (pcxh.Encoding == PCX_RunLength_Encoding) ) { is_PCX = 1; } } SDL_RWseek(src, start, SEEK_SET); return(is_PCX); }
static MAD_WRAPPER* init( SDL_RWops *src ) { MAD_WRAPPER *mad = new MAD_WRAPPER; SDL_RWseek( src, 0, SEEK_END ); mad->length = SDL_RWtell( src ); SDL_RWseek( src, 0, SEEK_SET ); mad->src = src; mad_stream_init( &mad->Stream ); mad_frame_init( &mad->Frame ); mad_synth_init( &mad->Synth ); mad->volume = 64; mad->input_buf = new unsigned char[ INPUT_BUFFER_SIZE ]; mad->output_buf = new unsigned char[ 1152*4*5 ]; /* 1152 because that's what mad has as a max; *4 because */ mad->output_buf_index = 0; mad->is_playing = false; return mad; }
/* Load a XXX type image from an SDL datasource */ SDL_Surface *IMG_LoadXXX_RW(SDL_RWops *src) { int start; const char *error = NULL; SDL_Surface *surface = NULL; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); /* Load the image here */ if ( error ) { SDL_RWseek(src, start, RW_SEEK_SET); if ( surface ) { SDL_FreeSurface(surface); surface = NULL; } IMG_SetError("%s", error); } return surface; }
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) { SDL_bool was_error; long fp_offset; int bmpPitch; int i, pad; SDL_Surface *surface; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; SDL_Palette *palette; Uint8 *bits; Uint8 *top, *end; SDL_bool topDown; int ExpandBMP; /* The Win32 BMP file header (14 bytes) */ char magic[2]; Uint32 bfSize; Uint16 bfReserved1; Uint16 bfReserved2; Uint32 bfOffBits; /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ Uint32 biSize; Sint32 biWidth; Sint32 biHeight; Uint16 biPlanes; Uint16 biBitCount; Uint32 biCompression; Uint32 biSizeImage; Sint32 biXPelsPerMeter; Sint32 biYPelsPerMeter; Uint32 biClrUsed; Uint32 biClrImportant; /* Make sure we are passed a valid data source */ surface = NULL; was_error = SDL_FALSE; if (src == NULL) { was_error = SDL_TRUE; goto done; } /* Read in the BMP file header */ fp_offset = SDL_RWtell(src); SDL_ClearError(); if (SDL_RWread(src, magic, 1, 2) != 2) { SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } if (SDL_strncmp(magic, "BM", 2) != 0) { SDL_SetError("File is not a Windows BMP file"); was_error = SDL_TRUE; goto done; } bfSize = SDL_ReadLE32(src); bfReserved1 = SDL_ReadLE16(src); bfReserved2 = SDL_ReadLE16(src); bfOffBits = SDL_ReadLE32(src); /* Read the Win32 BITMAPINFOHEADER */ biSize = SDL_ReadLE32(src); if (biSize == 12) { biWidth = (Uint32) SDL_ReadLE16(src); biHeight = (Uint32) SDL_ReadLE16(src); biPlanes = SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = BI_RGB; biSizeImage = 0; biXPelsPerMeter = 0; biYPelsPerMeter = 0; biClrUsed = 0; biClrImportant = 0; } else { biWidth = SDL_ReadLE32(src); biHeight = SDL_ReadLE32(src); biPlanes = SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = SDL_ReadLE32(src); biSizeImage = SDL_ReadLE32(src); biXPelsPerMeter = SDL_ReadLE32(src); biYPelsPerMeter = SDL_ReadLE32(src); biClrUsed = SDL_ReadLE32(src); biClrImportant = SDL_ReadLE32(src); } if (biHeight < 0) { topDown = SDL_TRUE; biHeight = -biHeight; } else { topDown = SDL_FALSE; } /* Check for read error */ if (SDL_strcmp(SDL_GetError(), "") != 0) { was_error = SDL_TRUE; goto done; } /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ switch (biBitCount) { case 1: case 4: ExpandBMP = biBitCount; biBitCount = 8; break; default: ExpandBMP = 0; break; } /* We don't support any BMP compression right now */ Rmask = Gmask = Bmask = Amask = 0; switch (biCompression) { case BI_RGB: /* If there are no masks, use the defaults */ if (bfOffBits == (14 + biSize)) { /* Default values for the BMP format */ switch (biBitCount) { case 15: case 16: Rmask = 0x7C00; Gmask = 0x03E0; Bmask = 0x001F; break; case 24: #if SDL_BYTEORDER == SDL_BIG_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; #else Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; #endif break; case 32: Amask = 0xFF000000; Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; break; default: break; } break; } /* Fall through -- read the RGB masks */ case BI_BITFIELDS: switch (biBitCount) { case 15: case 16: Rmask = SDL_ReadLE32(src); Gmask = SDL_ReadLE32(src); Bmask = SDL_ReadLE32(src); break; case 32: Rmask = SDL_ReadLE32(src); Gmask = SDL_ReadLE32(src); Bmask = SDL_ReadLE32(src); Amask = SDL_ReadLE32(src); break; default: break; } break; default: SDL_SetError("Compressed BMP files not supported"); was_error = SDL_TRUE; goto done; } /* Create a compatible surface, note that the colors are RGB ordered */ surface = SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, Amask); if (surface == NULL) { was_error = SDL_TRUE; goto done; } /* Load the palette, if any */ palette = (surface->format)->palette; if (palette) { if (biClrUsed == 0) { biClrUsed = 1 << biBitCount; } if ((int) biClrUsed > palette->ncolors) { palette->ncolors = biClrUsed; palette->colors = (SDL_Color *) SDL_realloc(palette->colors, palette->ncolors * sizeof(*palette->colors)); if (!palette->colors) { SDL_OutOfMemory(); was_error = SDL_TRUE; goto done; } } else if ((int) biClrUsed < palette->ncolors) { palette->ncolors = biClrUsed; } if (biSize == 12) { for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); palette->colors[i].unused = SDL_ALPHA_OPAQUE; } } else { for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); SDL_RWread(src, &palette->colors[i].unused, 1, 1); } } } /* Read the surface pixels. Note that the bmp image is upside down */ if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); was_error = SDL_TRUE; goto done; } top = (Uint8 *)surface->pixels; end = (Uint8 *)surface->pixels+(surface->h*surface->pitch); switch (ExpandBMP) { case 1: bmpPitch = (biWidth + 7) >> 3; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; case 4: bmpPitch = (biWidth + 1) >> 1; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; default: pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0); break; } if (topDown) { bits = top; } else { bits = end - surface->pitch; } while (bits >= top && bits < end) { switch (ExpandBMP) { case 1: case 4:{ Uint8 pixel = 0; int shift = (8 - ExpandBMP); for (i = 0; i < surface->w; ++i) { if (i % (8 / ExpandBMP) == 0) { if (!SDL_RWread(src, &pixel, 1, 1)) { SDL_SetError("Error reading from BMP"); was_error = SDL_TRUE; goto done; } } *(bits + i) = (pixel >> shift); pixel <<= ExpandBMP; } } break; default: if (SDL_RWread(src, bits, 1, surface->pitch) != surface->pitch) { SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } #if SDL_BYTEORDER == SDL_BIG_ENDIAN /* Byte-swap the pixels if needed. Note that the 24bpp case has already been taken care of above. */ switch (biBitCount) { case 15: case 16:{ Uint16 *pix = (Uint16 *) bits; for (i = 0; i < surface->w; i++) pix[i] = SDL_Swap16(pix[i]); break; } case 32:{ Uint32 *pix = (Uint32 *) bits; for (i = 0; i < surface->w; i++) pix[i] = SDL_Swap32(pix[i]); break; } } #endif break; } /* Skip padding bytes, ugh */ if (pad) { Uint8 padbyte; for (i = 0; i < pad; ++i) { SDL_RWread(src, &padbyte, 1, 1); } } if (topDown) { bits += surface->pitch; } else { bits -= surface->pitch; } } done: if (was_error) { if (src) { SDL_RWseek(src, fp_offset, RW_SEEK_SET); } if (surface) { SDL_FreeSurface(surface); } surface = NULL; } if (freesrc && src) { SDL_RWclose(src); } return (surface); }
int SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) { long fp_offset; int i, pad; SDL_Surface *surface; Uint8 *bits; /* The Win32 BMP file header (14 bytes) */ char magic[2] = { 'B', 'M' }; Uint32 bfSize; Uint16 bfReserved1; Uint16 bfReserved2; Uint32 bfOffBits; /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ Uint32 biSize; Sint32 biWidth; Sint32 biHeight; Uint16 biPlanes; Uint16 biBitCount; Uint32 biCompression; Uint32 biSizeImage; Sint32 biXPelsPerMeter; Sint32 biYPelsPerMeter; Uint32 biClrUsed; Uint32 biClrImportant; /* Make sure we have somewhere to save */ surface = NULL; if (dst) { SDL_bool save32bit = SDL_FALSE; #ifdef SAVE_32BIT_BMP /* We can save alpha information in a 32-bit BMP */ if (saveme->map->info.flags & SDL_COPY_COLORKEY || saveme->format->Amask) { save32bit = SDL_TRUE; } #endif /* SAVE_32BIT_BMP */ if (saveme->format->palette && !save32bit) { if (saveme->format->BitsPerPixel == 8) { surface = saveme; } else { SDL_SetError("%d bpp BMP files not supported", saveme->format->BitsPerPixel); } } else if ((saveme->format->BitsPerPixel == 24) && #if SDL_BYTEORDER == SDL_LIL_ENDIAN (saveme->format->Rmask == 0x00FF0000) && (saveme->format->Gmask == 0x0000FF00) && (saveme->format->Bmask == 0x000000FF) #else (saveme->format->Rmask == 0x000000FF) && (saveme->format->Gmask == 0x0000FF00) && (saveme->format->Bmask == 0x00FF0000) #endif ) { surface = saveme; } else { SDL_PixelFormat format; /* If the surface has a colorkey or alpha channel we'll save a 32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */ if (save32bit) { SDL_InitFormat(&format, #if SDL_BYTEORDER == SDL_LIL_ENDIAN SDL_PIXELFORMAT_ARGB8888 #else SDL_PIXELFORMAT_BGRA8888 #endif ); } else { SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24); } surface = SDL_ConvertSurface(saveme, &format, 0); if (!surface) { SDL_SetError("Couldn't convert image to %d bpp", format.BitsPerPixel); } } } if (surface && (SDL_LockSurface(surface) == 0)) { const int bw = surface->w * surface->format->BytesPerPixel; /* Set the BMP file header values */ bfSize = 0; /* We'll write this when we're done */ bfReserved1 = 0; bfReserved2 = 0; bfOffBits = 0; /* We'll write this when we're done */ /* Write the BMP file header values */ fp_offset = SDL_RWtell(dst); SDL_ClearError(); SDL_RWwrite(dst, magic, 2, 1); SDL_WriteLE32(dst, bfSize); SDL_WriteLE16(dst, bfReserved1); SDL_WriteLE16(dst, bfReserved2); SDL_WriteLE32(dst, bfOffBits); /* Set the BMP info values */ biSize = 40; biWidth = surface->w; biHeight = surface->h; biPlanes = 1; biBitCount = surface->format->BitsPerPixel; biCompression = BI_RGB; biSizeImage = surface->h * surface->pitch; biXPelsPerMeter = 0; biYPelsPerMeter = 0; if (surface->format->palette) { biClrUsed = surface->format->palette->ncolors; } else { biClrUsed = 0; } biClrImportant = 0; /* Write the BMP info values */ SDL_WriteLE32(dst, biSize); SDL_WriteLE32(dst, biWidth); SDL_WriteLE32(dst, biHeight); SDL_WriteLE16(dst, biPlanes); SDL_WriteLE16(dst, biBitCount); SDL_WriteLE32(dst, biCompression); SDL_WriteLE32(dst, biSizeImage); SDL_WriteLE32(dst, biXPelsPerMeter); SDL_WriteLE32(dst, biYPelsPerMeter); SDL_WriteLE32(dst, biClrUsed); SDL_WriteLE32(dst, biClrImportant); /* Write the palette (in BGR color order) */ if (surface->format->palette) { SDL_Color *colors; int ncolors; colors = surface->format->palette->colors; ncolors = surface->format->palette->ncolors; for (i = 0; i < ncolors; ++i) { SDL_RWwrite(dst, &colors[i].b, 1, 1); SDL_RWwrite(dst, &colors[i].g, 1, 1); SDL_RWwrite(dst, &colors[i].r, 1, 1); SDL_RWwrite(dst, &colors[i].unused, 1, 1); } } /* Write the bitmap offset */ bfOffBits = SDL_RWtell(dst) - fp_offset; if (SDL_RWseek(dst, fp_offset + 10, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } SDL_WriteLE32(dst, bfOffBits); if (SDL_RWseek(dst, fp_offset + bfOffBits, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } /* Write the bitmap image upside down */ bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch); pad = ((bw % 4) ? (4 - (bw % 4)) : 0); while (bits > (Uint8 *) surface->pixels) { bits -= surface->pitch; if (SDL_RWwrite(dst, bits, 1, bw) != bw) { SDL_Error(SDL_EFWRITE); break; } if (pad) { const Uint8 padbyte = 0; for (i = 0; i < pad; ++i) { SDL_RWwrite(dst, &padbyte, 1, 1); } } } /* Write the BMP file size */ bfSize = SDL_RWtell(dst) - fp_offset; if (SDL_RWseek(dst, fp_offset + 2, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } SDL_WriteLE32(dst, bfSize); if (SDL_RWseek(dst, fp_offset + bfSize, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); } /* Close it up.. */ SDL_UnlockSurface(surface); if (surface != saveme) { SDL_FreeSurface(surface); } } if (freedst && dst) { SDL_RWclose(dst); } return ((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1); }
size_t BaseFile::tell() { SDL_RWops * rw = (SDL_RWops*)handle; return SDL_RWtell(rw); }
SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) { int start; SDL_Surface *Image; Uint8 id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk; Uint32 size, bytesloaded, nbcolors; Uint32 i, j, bytesperline, nbplanes, stencil, plane, h; Uint32 remainingbytes; Uint32 width; BMHD bmhd; char *error; Uint8 flagHAM,flagEHB; Image = NULL; error = NULL; MiniBuf = NULL; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } /* Should be the size of the file minus 4+4 ( 'FORM'+size ) */ if ( !SDL_RWread( src, &size, 4, 1 ) ) { error="error reading IFF chunk size"; goto done; } /* As size is not used here, no need to swap it */ if ( memcmp( id, "FORM", 4 ) != 0 ) { error="not a IFF file"; goto done; } if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } pbm = 0; /* File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap */ if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1; else if ( memcmp( id, "ILBM", 4 ) ) { error="not a IFF picture"; goto done; } nbcolors = 0; memset( &bmhd, 0, sizeof( BMHD ) ); flagHAM = 0; flagEHB = 0; while ( memcmp( id, "BODY", 4 ) != 0 ) { if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } if ( !SDL_RWread( src, &size, 4, 1 ) ) { error="error reading IFF chunk size"; goto done; } bytesloaded = 0; size = SDL_SwapBE32( size ); if ( !memcmp( id, "BMHD", 4 ) ) /* Bitmap header */ { if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) ) { error="error reading BMHD chunk"; goto done; } bytesloaded = sizeof( BMHD ); bmhd.w = SDL_SwapBE16( bmhd.w ); bmhd.h = SDL_SwapBE16( bmhd.h ); bmhd.x = SDL_SwapBE16( bmhd.x ); bmhd.y = SDL_SwapBE16( bmhd.y ); bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor ); bmhd.Lpage = SDL_SwapBE16( bmhd.Lpage ); bmhd.Hpage = SDL_SwapBE16( bmhd.Hpage ); } if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */ { if ( !SDL_RWread( src, &colormap, size, 1 ) ) { error="error reading CMAP chunk"; goto done; } bytesloaded = size; nbcolors = size / 3; } if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode */ { Uint32 viewmodes; if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) ) { error="error reading CAMG chunk"; goto done; } bytesloaded = size; viewmodes = SDL_SwapBE32( viewmodes ); if ( viewmodes & 0x0800 ) flagHAM = 1; if ( viewmodes & 0x0080 ) flagEHB = 1; } if ( memcmp( id, "BODY", 4 ) ) { if ( size & 1 ) ++size; /* padding ! */ size -= bytesloaded; /* skip the remaining bytes of this chunk */ if ( size ) SDL_RWseek( src, size, RW_SEEK_CUR ); } } /* compute some usefull values, based on the bitmap header */ width = ( bmhd.w + 15 ) & 0xFFFFFFF0; /* Width in pixels modulo 16 */ bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2; nbplanes = bmhd.planes; if ( pbm ) /* File format : 'Packed Bitmap' */ { bytesperline *= 8; nbplanes = 1; } stencil = (bmhd.mask & 1); /* There is a mask ( 'stencil' ) */ /* Allocate memory for a temporary buffer ( used for decompression/deinterleaving ) */ MiniBuf = (void *)malloc( bytesperline * (nbplanes + stencil) ); if ( MiniBuf == NULL ) { error="no enough memory for temporary buffer"; goto done; } if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL ) goto done; if ( bmhd.mask & 2 ) /* There is a transparent color */ SDL_SetColorKey( Image, SDL_SRCCOLORKEY, bmhd.tcolor ); /* Update palette informations */ /* There is no palette in 24 bits ILBM file */ if ( nbcolors>0 && flagHAM==0 ) { /* FIXME: Should this include the stencil? See comment below */ int nbrcolorsfinal = 1 << (nbplanes + stencil); ptr = &colormap[0]; for ( i=0; i<nbcolors; i++ ) { Image->format->palette->colors[i].r = *ptr++; Image->format->palette->colors[i].g = *ptr++; Image->format->palette->colors[i].b = *ptr++; } /* Amiga EHB mode (Extra-Half-Bright) */ /* 6 bitplanes mode with a 32 colors palette */ /* The 32 last colors are the same but divided by 2 */ /* Some Amiga pictures save 64 colors with 32 last wrong colors, */ /* they shouldn't !, and here we overwrite these 32 bad colors. */ if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 ) { nbcolors = 64; ptr = &colormap[0]; for ( i=32; i<64; i++ ) { Image->format->palette->colors[i].r = (*ptr++)/2; Image->format->palette->colors[i].g = (*ptr++)/2; Image->format->palette->colors[i].b = (*ptr++)/2; } } /* If nbcolors < 2^nbplanes, repeat the colormap */ /* This happens when pictures have a stencil mask */ if ( nbrcolorsfinal > (1<<bmhd.planes) ) { nbrcolorsfinal = (1<<bmhd.planes); } for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ ) { Image->format->palette->colors[i].r = Image->format->palette->colors[i%nbcolors].r; Image->format->palette->colors[i].g = Image->format->palette->colors[i%nbcolors].g; Image->format->palette->colors[i].b = Image->format->palette->colors[i%nbcolors].b; } if ( !pbm ) Image->format->palette->ncolors = nbrcolorsfinal; } /* Get the bitmap */ for ( h=0; h < bmhd.h; h++ ) { /* uncompress the datas of each planes */ for ( plane=0; plane < (nbplanes+stencil); plane++ ) { ptr = MiniBuf + ( plane * bytesperline ); remainingbytes = bytesperline; if ( bmhd.tcomp == 1 ) /* Datas are compressed */ { do { if ( !SDL_RWread( src, &count, 1, 1 ) ) { error="error reading BODY chunk"; goto done; } if ( count & 0x80 ) { count ^= 0xFF; count += 2; /* now it */ if ( ( count > remainingbytes ) || !SDL_RWread( src, &color, 1, 1 ) ) { error="error reading BODY chunk"; goto done; } memset( ptr, color, count ); } else { ++count; if ( ( count > remainingbytes ) || !SDL_RWread( src, ptr, count, 1 ) ) { error="error reading BODY chunk"; goto done; } } ptr += count; remainingbytes -= count; } while ( remainingbytes > 0 ); } else { if ( !SDL_RWread( src, ptr, bytesperline, 1 ) ) { error="error reading BODY chunk"; goto done; } } } /* One line has been read, store it ! */ ptr = Image->pixels; if ( nbplanes==24 || flagHAM==1 ) ptr += h * width * 3; else ptr += h * width; if ( pbm ) /* File format : 'Packed Bitmap' */ { memcpy( ptr, MiniBuf, width ); } else /* We have to un-interlace the bits ! */ { if ( nbplanes!=24 && flagHAM==0 ) { size = ( width + 7 ) / 8; for ( i=0; i < size; i++ ) { memset( ptr, 0, 8 ); for ( plane=0; plane < (nbplanes + stencil); plane++ ) { color = *( MiniBuf + i + ( plane * bytesperline ) ); msk = 0x80; for ( j=0; j<8; j++ ) { if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j ); else ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 ); msk >>= 1; } } ptr += 8; } } else {
/* read XPM from either array or RWops */ static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src) { int start = 0; SDL_Surface *image = NULL; int index; int x, y; int w, h, ncolors, cpp; int indexed; Uint8 *dst; struct color_hash *colors = NULL; SDL_Color *im_colors = NULL; char *keystrings = NULL, *nextkey; char *line; char ***xpmlines = NULL; int pixels_len; error = NULL; linebuf = NULL; buflen = 0; if ( src ) start = SDL_RWtell(src); if(xpm) xpmlines = &xpm; line = get_next_line(xpmlines, src, 0); if(!line) goto done; /* * The header string of an XPMv3 image has the format * * <width> <height> <ncolors> <cpp> [ <hotspot_x> <hotspot_y> ] * * where the hotspot coords are intended for mouse cursors. * Right now we don't use the hotspots but it should be handled * one day. */ if(sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { error = "Invalid format description"; goto done; } keystrings = malloc(ncolors * cpp); if(!keystrings) { error = "Out of memory"; goto done; } nextkey = keystrings; /* Create the new surface */ if(ncolors <= 256) { indexed = 1; image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); im_colors = image->format->palette->colors; image->format->palette->ncolors = ncolors; } else { indexed = 0; image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0xff0000, 0x00ff00, 0x0000ff, 0); } if(!image) { /* Hmm, some SDL error (out of memory?) */ goto done; } /* Read the colors */ colors = create_colorhash(ncolors); if (!colors) { error = "Out of memory"; goto done; } for(index = 0; index < ncolors; ++index ) { char *p; line = get_next_line(xpmlines, src, 0); if(!line) goto done; p = line + cpp + 1; /* parse a colour definition */ for(;;) { char nametype; char *colname; Uint32 rgb, pixel; SKIPSPACE(p); if(!*p) { error = "colour parse error"; goto done; } nametype = *p; SKIPNONSPACE(p); SKIPSPACE(p); colname = p; SKIPNONSPACE(p); if(nametype == 's') continue; /* skip symbolic colour names */ if(!color_to_rgb(colname, p - colname, &rgb)) continue; memcpy(nextkey, line, cpp); if(indexed) { SDL_Color *c = im_colors + index; c->r = (Uint8)(rgb >> 16); c->g = (Uint8)(rgb >> 8); c->b = (Uint8)(rgb); pixel = index; } else pixel = rgb; add_colorhash(colors, nextkey, cpp, pixel); nextkey += cpp; if(rgb == 0xffffffff) SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel); break; } }
SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src) { int start; SDL_Surface *surface = NULL; int width, height; int maxval, y, bpl; Uint8 *row; Uint8 *buf = NULL; char *error = NULL; Uint8 magic[2]; int ascii; enum { PBM, PGM, PPM, PAM } kind; #define ERROR(s) do { error = (s); goto done; } while(0) if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); SDL_RWread(src, magic, 2, 1); kind = magic[1] - '1'; ascii = 1; if(kind >= 3) { ascii = 0; kind -= 3; } width = ReadNumber(src); height = ReadNumber(src); if(width <= 0 || height <= 0) ERROR("Unable to read image width and height"); if(kind != PBM) { maxval = ReadNumber(src); if(maxval <= 0 || maxval > 255) ERROR("unsupported PNM format"); } else maxval = 255; /* never scale PBMs */ /* binary PNM allows just a single character of whitespace after the last parameter, and we've already consumed it */ if(kind == PPM) { /* 24-bit surface in R,G,B byte order */ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, #else 0x00ff0000, 0x0000ff00, 0x000000ff, #endif 0); } else { /* load PBM/PGM as 8-bit indexed images */ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0); } if ( surface == NULL ) ERROR("Out of memory"); bpl = width * surface->format->BytesPerPixel; if(kind == PGM) { SDL_Color *c = surface->format->palette->colors; int i; for(i = 0; i < 256; i++) c[i].r = c[i].g = c[i].b = i; surface->format->palette->ncolors = 256; } else if(kind == PBM) { /* for some reason PBM has 1=black, 0=white */ SDL_Color *c = surface->format->palette->colors; c[0].r = c[0].g = c[0].b = 255; c[1].r = c[1].g = c[1].b = 0; surface->format->palette->ncolors = 2; bpl = (width + 7) >> 3; buf = malloc(bpl); if(buf == NULL) ERROR("Out of memory"); }
Sint64 u8file::ftell(){ return SDL_RWtell(m_file); }
static long sdl_tell_func(void *datasource) { return (long)SDL_RWtell((SDL_RWops*)datasource); }
bool Serializer::writeRoomData() { // Write the enable status for the spots of all nodes of all rooms if (!SDL_WriteBE16(_rw, Control::instance().numRooms())) return false; for (Room *room : Control::instance().rooms()) { if (!SDL_WriteBE16(_rw, room->numNodes())) return false; if (room->hasNodes()) { room->beginIteratingNodes(); do { Node *node = room->iterator(); if (!SDL_WriteBE16(_rw, node->numSpots())) return false; if (node->hasSpots()) { node->beginIteratingSpots(); do { if (!SDL_WriteU8(_rw, node->currentSpot()->isEnabled())) return false; } while (node->iterateSpots()); } } while (room->iterateNodes()); } } Room *room = Control::instance().currentRoom(); // Write node number uint16_t nodeIdx = 0; if (room->hasNodes()) { room->beginIteratingNodes(); do { if (room->iterator() == room->currentNode()) break; nodeIdx++; } while (room->iterateNodes()); } if (!SDL_WriteBE16(_rw, nodeIdx)) return false; // Write camera angles int hAngle = CameraManager::instance().angleHorizontal(); const std::string hAngleStr = std::to_string(hAngle); if (!SDL_WriteU8(_rw, hAngleStr.length())) return false; if (!SDL_RWwrite(_rw, hAngleStr.c_str(), hAngleStr.length(), 1)) return false; int vAngle = CameraManager::instance().angleVertical(); const std::string vAngleStr = std::to_string(vAngle); if (!SDL_WriteU8(_rw, vAngleStr.length())) return false; if (!SDL_RWwrite(_rw, vAngleStr.c_str(), vAngleStr.length(), 1)) return false; float fov = CameraManager::instance().fieldOfView(); const std::string fovStr = std::to_string(fov); if (!SDL_WriteU8(_rw, fovStr.length())) return false; if (!SDL_RWwrite(_rw, fovStr.c_str(), fovStr.length(), 1)) return false; // Write audio states if (!SDL_WriteBE16(_rw, room->arrayOfAudios().size())) return false; for (Audio *audio : room->arrayOfAudios()) { if (!SDL_WriteU8(_rw, audio->state())) return false; } // Write timers int64_t timersPtr = SDL_RWtell(_rw); if (timersPtr < 0) return false; if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual number of timers return false; uint16_t numTimers = 0; for (const auto &timer : TimerManager::instance().timers()) { if (timer.type != DGTimerNormal || !timer.isEnabled || (!timer.isLoopable && timer.hasTriggered)) continue; double elapsed = TimerManager::instance().timeElapsed(timer); if (timer.trigger - elapsed > 0) { const std::string triggerStr = std::to_string(timer.trigger); if (!SDL_WriteU8(_rw, timer.isLoopable)) return false; if (!SDL_WriteU8(_rw, triggerStr.length())) return false; if (!SDL_RWwrite(_rw, triggerStr.c_str(), triggerStr.length(), 1)) return false; const std::string elapsedStr = std::to_string(elapsed); if (!SDL_WriteU8(_rw, elapsedStr.length())) return false; if (!SDL_RWwrite(_rw, elapsedStr.c_str(), elapsedStr.length(), 1)) return false; lua_rawgeti(_L, LUA_REGISTRYINDEX, timer.luaHandler); // Push timer function to top of stack int64_t funcSizePtr = SDL_RWtell(_rw); if (funcSizePtr < 0) return false; if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual function size return false; int64_t beforeFuncPtr = SDL_RWtell(_rw); if (beforeFuncPtr < 0) return false; int errCode = lua_dump(_L, writeFunction, _rw); if (errCode != 0) return false; int64_t afterFuncPtr = SDL_RWtell(_rw); if (afterFuncPtr < 0) return false; uint16_t numBytesWritten = afterFuncPtr - beforeFuncPtr; if (SDL_RWseek(_rw, funcSizePtr, RW_SEEK_SET) < 0) return false; if (!SDL_WriteBE16(_rw, numBytesWritten)) return false; if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end return false; numTimers++; } } if (SDL_RWseek(_rw, timersPtr, RW_SEEK_SET) < 0) return false; if (!SDL_WriteBE16(_rw, numTimers)) return false; if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end return false; // Write control mode if (!SDL_WriteU8(_rw, Config::instance().controlMode)) return false; return true; }
/* 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); }
static int AU_open(Sound_Sample *sample, const char *ext) { Sound_SampleInternal *internal = sample->opaque; SDL_RWops *rw = internal->rw; int skip, hsize, i, bytes_per_second; struct au_file_hdr hdr; struct audec *dec; char c; /* read_au_header() will do byte order swapping. */ BAIL_IF_MACRO(!read_au_header(rw, &hdr), "AU: bad header", 0); dec = malloc(sizeof *dec); BAIL_IF_MACRO(dec == NULL, ERR_OUT_OF_MEMORY, 0); internal->decoder_private = dec; if (hdr.magic == AU_MAGIC) { /* valid magic */ dec->encoding = hdr.encoding; switch(dec->encoding) { case AU_ENC_ULAW_8: /* Convert 8-bit µ-law to 16-bit linear on the fly. This is slightly wasteful if the audio driver must convert them back, but µ-law only devices are rare (mostly _old_ Suns) */ sample->actual.format = AUDIO_S16SYS; break; case AU_ENC_LINEAR_8: sample->actual.format = AUDIO_S8; break; case AU_ENC_LINEAR_16: sample->actual.format = AUDIO_S16MSB; break; default: free(dec); BAIL_MACRO("AU: Unsupported .au encoding", 0); } /* switch */ sample->actual.rate = hdr.sample_rate; sample->actual.channels = hdr.channels; dec->remaining = hdr.data_size; hsize = hdr.hdr_size; /* skip remaining part of header (input may be unseekable) */ for (i = HDR_SIZE; i < hsize; i++) { if (SDL_RWread(rw, &c, 1, 1) != 1) { free(dec); BAIL_MACRO(ERR_IO_ERROR, 0); } /* if */ } /* for */ } /* if */ else if (__Sound_strcasecmp(ext, "au") == 0) { /* * A number of files in the wild have the .au extension but no valid * header; these are traditionally assumed to be 8kHz µ-law. Handle * them here only if the extension is recognized. */ SNDDBG(("AU: Invalid header, assuming raw 8kHz µ-law.\n")); /* if seeking fails, we lose 24 samples. big deal */ SDL_RWseek(rw, -HDR_SIZE, SEEK_CUR); dec->encoding = AU_ENC_ULAW_8; dec->remaining = (Uint32)-1; /* no limit */ sample->actual.format = AUDIO_S16SYS; sample->actual.rate = 8000; sample->actual.channels = 1; } /* else if */ else { free(dec); BAIL_MACRO("AU: Not an .AU stream.", 0); } /* else */ bytes_per_second = ( ( dec->encoding == AU_ENC_LINEAR_16 ) ? 2 : 1 ) * sample->actual.rate * sample->actual.channels ; internal->total_time = ((dec->remaining == -1) ? (-1) : ( ( dec->remaining / bytes_per_second ) * 1000 ) + ( ( dec->remaining % bytes_per_second ) * 1000 / bytes_per_second ) ); sample->flags = SOUND_SAMPLEFLAG_CANSEEK; dec->total = dec->remaining; dec->start_offset = SDL_RWtell(rw); SNDDBG(("AU: Accepting data stream.\n")); return(1); } /* AU_open */
static Sint64 sdl_tell_func(void *datasource) { return SDL_RWtell((SDL_RWops*)datasource); }
long File::tell () const { return SDL_RWtell(_file); }
static long LMM_Tell(struct MREADER *mr) { struct LMM_MREADER *lmmmr = (struct LMM_MREADER *)mr; return SDL_RWtell(lmmmr->rw) - lmmmr->offset; }
static bool isJpg(const unsigned char * data, int length){ /* TODO */ return false; #if 0 int start; int is_JPG; int in_scan; Uint8 magic[4]; /* This detection code is by Steaphan Greene <*****@*****.**> */ /* Blame me, not Sam, if this doesn't work right. */ /* And don't forget to report the problem to the the sdl list too! */ if ( !src ) return 0; start = SDL_RWtell(src); is_JPG = 0; in_scan = 0; if ( SDL_RWread(src, magic, 2, 1) ) { if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) { is_JPG = 1; while (is_JPG == 1) { if(SDL_RWread(src, magic, 1, 2) != 2) { is_JPG = 0; } else if( (magic[0] != 0xFF) && (in_scan == 0) ) { is_JPG = 0; } else if( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) { /* Extra padding in JPEG (legal) */ /* or this is data and we are scanning */ SDL_RWseek(src, -1, RW_SEEK_CUR); } else if(magic[1] == 0xD9) { /* Got to end of good JPEG */ break; } else if( (in_scan == 1) && (magic[1] == 0x00) ) { /* This is an encoded 0xFF within the data */ } else if( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) { /* These have nothing else */ } else if(SDL_RWread(src, magic+2, 1, 2) != 2) { is_JPG = 0; } else { /* Yes, it's big-endian */ Uint32 start; Uint32 size; Uint32 end; start = SDL_RWtell(src); size = (magic[2] << 8) + magic[3]; end = SDL_RWseek(src, size-2, RW_SEEK_CUR); if ( end != start + size - 2 ) is_JPG = 0; if ( magic[1] == 0xDA ) { /* Now comes the actual JPEG meat */ #ifdef FAST_IS_JPEG /* Ok, I'm convinced. It is a JPEG. */ break; #else /* I'm not convinced. Prove it! */ in_scan = 1; #endif } } } } } SDL_RWseek(src, start, RW_SEEK_SET); return(is_JPG); #endif }