NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *src, int freesrc) { NativeMidiSong *retval = NULL; void *buf = NULL; Sint64 len = 0; CFDataRef data = NULL; if (SDL_RWseek(src, 0, RW_SEEK_END) < 0) goto fail; len = SDL_RWtell(src); if (len < 0) goto fail; if (SDL_RWseek(src, 0, RW_SEEK_SET) < 0) goto fail; buf = malloc(len); if (buf == NULL) goto fail; if (SDL_RWread(src, buf, len, 1) != 1) goto fail; retval = malloc(sizeof(NativeMidiSong)); if (retval == NULL) goto fail; memset(retval, '\0', sizeof (*retval)); if (NewMusicPlayer(&retval->player) != noErr) goto fail; if (NewMusicSequence(&retval->sequence) != noErr) goto fail; data = CFDataCreate(NULL, (const UInt8 *) buf, len); if (data == NULL) goto fail; free(buf); buf = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 /* MusicSequenceLoadSMFData() (avail. in 10.2, no 64 bit) is * equivalent to calling MusicSequenceLoadSMFDataWithFlags() * with a flags value of 0 (avail. in 10.3, avail. 64 bit). * So, we use MusicSequenceLoadSMFData() for powerpc versions * but the *WithFlags() on intel which require 10.4 anyway. */ # if defined(__ppc__) || defined(__POWERPC__) if (MusicSequenceLoadSMFData(song->sequence, data) != noErr) goto fail; # else if (MusicSequenceLoadSMFDataWithFlags(retval->sequence, data, 0) != noErr) goto fail; # endif #else /* MusicSequenceFileLoadData() requires 10.5 or later. */ if (MusicSequenceFileLoadData(retval->sequence, data, 0, 0) != noErr) goto fail; #endif CFRelease(data); data = NULL; if (GetSequenceLength(retval->sequence, &retval->endTime) != noErr) goto fail; if (MusicPlayerSetSequence(retval->player, retval->sequence) != noErr) goto fail; if (freesrc) SDL_RWclose(src); return retval; fail: if (retval) { if (retval->sequence) DisposeMusicSequence(retval->sequence); if (retval->player) DisposeMusicPlayer(retval->player); free(retval); } if (data) CFRelease(data); if (buf) free(buf); return NULL; }
static int sdl_seek_func(void *datasource, ogg_int64_t offset, int whence) { return SDL_RWseek((SDL_RWops*)datasource, (int)offset, whence); }
SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src) { Sint64 start; TIFF* tiff; SDL_Surface* surface = NULL; Uint32 img_width, img_height; Uint32 Rmask, Gmask, Bmask, Amask; Uint32 x, y; Uint32 half; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( !IMG_Init(IMG_INIT_TIF) ) { return NULL; } /* turn off memory mapped access with the m flag */ tiff = lib.TIFFClientOpen("SDL_image", "rm", (thandle_t)src, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, tiff_map, tiff_unmap); if(!tiff) goto error; /* Retrieve the dimensions of the image from the TIFF tags */ lib.TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); lib.TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; surface = SDL_CreateRGBSurface(SDL_SWSURFACE, img_width, img_height, 32, Rmask, Gmask, Bmask, Amask); if(!surface) goto error; if(!lib.TIFFReadRGBAImage(tiff, img_width, img_height, (uint32 *)surface->pixels, 0)) goto error; /* libtiff loads the image upside-down, flip it back */ half = img_height / 2; for(y = 0; y < half; y++) { Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4; Uint32 *bot = (Uint32 *)surface->pixels + (img_height - y - 1) * surface->pitch/4; for(x = 0; x < img_width; x++) { Uint32 tmp = top[x]; top[x] = bot[x]; bot[x] = tmp; } } lib.TIFFClose(tiff); return surface; error: SDL_RWseek(src, start, RW_SEEK_SET); if ( surface ) { SDL_FreeSurface(surface); } return NULL; }
bool replay_read(Replay *rpy, SDL_RWops *file, ReplayReadMode mode, const char *source) { int64_t filesize; // must be signed SDL_RWops *vfile = file; if(!source) { source = "<unknown>"; } if(!(mode & REPLAY_READ_ALL) ) { log_fatal("%s: Called with invalid read mode %x", source, mode); } mode &= REPLAY_READ_ALL; filesize = SDL_RWsize(file); if(filesize < 0) { log_warn("%s: SDL_RWsize() failed: %s", source, SDL_GetError()); } if(mode & REPLAY_READ_META) { memset(rpy, 0, sizeof(Replay)); if(filesize > 0 && filesize <= sizeof(replay_magic_header) + 2) { log_warn("%s: Replay file is too short (%"PRIi64")", source, filesize); return false; } size_t ofs = 0; if(!replay_read_header(rpy, file, filesize, &ofs, source)) { return false; } bool compression = false; if(rpy->version & REPLAY_VERSION_COMPRESSION_BIT) { if(rpy->fileoffset < SDL_RWtell(file)) { log_warn("%s: Invalid offset %"PRIi32"", source, rpy->fileoffset); return false; } vfile = SDL_RWWrapZReader(SDL_RWWrapSegment(file, ofs, rpy->fileoffset, false), REPLAY_COMPRESSION_CHUNK_SIZE, true); filesize = -1; compression = true; } if(!replay_read_meta(rpy, vfile, filesize, source)) { if(compression) { SDL_RWclose(vfile); } return false; } if(compression) { SDL_RWclose(vfile); vfile = file; } else { rpy->fileoffset = SDL_RWtell(file); } } if(mode & REPLAY_READ_EVENTS) { if(!(mode & REPLAY_READ_META)) { if(!rpy->fileoffset) { log_fatal("%s: Tried to read events before reading metadata", source); } for(int i = 0; i < rpy->numstages; ++i) { if(rpy->stages[i].events) { log_warn("%s: BUG: Reading events into a replay that already had events, call replay_destroy_events() if this is intended", source); replay_destroy_events(rpy); break; } } if(SDL_RWseek(file, rpy->fileoffset, RW_SEEK_SET) < 0) { log_warn("%s: SDL_RWseek() failed: %s", source, SDL_GetError()); return false; } } bool compression = false; if(rpy->version & REPLAY_VERSION_COMPRESSION_BIT) { vfile = SDL_RWWrapZReader(file, REPLAY_COMPRESSION_CHUNK_SIZE, false); filesize = -1; compression = true; } if(!replay_read_events(rpy, vfile, filesize, source)) { if(compression) { SDL_RWclose(vfile); } replay_destroy_events(rpy); return false; } if(compression) { SDL_RWclose(vfile); } // useless byte to simplify the premature EOF check, can be anything SDL_ReadU8(file); } return true; }
size_t THSoundArchive::getSoundDuration(size_t iIndex) { SDL_RWops *pFile = loadSound(iIndex); if(!pFile) return 0; uint16_t iWaveAudioFormat = 0; uint16_t iWaveChannelCount = 0; uint32_t iWaveSampleRate = 0; uint32_t iWaveByteRate = 0; uint16_t iWaveBlockAlign = 0; uint16_t iWaveBitsPerSample = 0; uint32_t iWaveDataLength = 0; // This is a very crude RIFF parser, but it does the job. uint32_t iFourCC; uint32_t iChunkLength; for(;;) { if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1) break; if(SDL_RWread(pFile, &iChunkLength, 4, 1) != 1) break; if(iFourCC == FOURCC('R','I','F','F') || iFourCC == FOURCC('L','I','S','T')) { if(iChunkLength >= 4) { if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1) break; else continue; } } if(iFourCC == FOURCC('f','m','t',' ') && iChunkLength >= 16) { if(SDL_RWread(pFile, &iWaveAudioFormat, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveChannelCount, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveSampleRate, 4, 1) != 1) break; if(SDL_RWread(pFile, &iWaveByteRate, 4, 1) != 1) break; if(SDL_RWread(pFile, &iWaveBlockAlign, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveBitsPerSample, 2, 1) != 1) break; iChunkLength -= 16; } if(iFourCC == FOURCC('d','a','t','a')) { iWaveDataLength = iChunkLength; } if(SDL_RWseek(pFile, iChunkLength + (iChunkLength & 1), SEEK_CUR) == -1) break; } SDL_RWclose(pFile); if(iWaveAudioFormat != 1 || iWaveChannelCount == 0 || iWaveSampleRate == 0 || iWaveDataLength == 0 || iWaveBitsPerSample == 0) { return 0; } #define mul64(a, b) (static_cast<uint64_t>(a) * static_cast<uint64_t>(b)) return static_cast<size_t>(mul64(iWaveDataLength, 8000) / mul64(mul64(iWaveBitsPerSample, iWaveChannelCount), iWaveSampleRate)); #undef mul64 }
SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) { int was_error; long fp_offset; int bmpPitch; int i, pad; SDL_Surface *surface; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; SDL_Palette *palette; Uint8 *bits; 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 = 0; if ( src == NULL ) { was_error = 1; 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 = 1; goto done; } if ( strncmp(magic, "BM", 2) != 0 ) { SDL_SetError("File is not a Windows BMP file"); was_error = 1; 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); } /* Check for read error */ if ( strcmp(SDL_GetError(), "") != 0 ) { was_error = 1; 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 = 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; break; #endif case 32: 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: case 32: Rmask = SDL_ReadLE32(src); Gmask = SDL_ReadLE32(src); Bmask = SDL_ReadLE32(src); break; default: break; } break; default: SDL_SetError("Compressed BMP files not supported"); was_error = 1; goto done; } /* Create a compatible surface, note that the colors are RGB ordered */ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); if ( surface == NULL ) { was_error = 1; goto done; } /* Load the palette, if any */ palette = (surface->format)->palette; if ( palette ) { if ( biClrUsed == 0 ) { biClrUsed = 1 << biBitCount; } 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 = 0; } } 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); } } palette->ncolors = biClrUsed; } /* Read the surface pixels. Note that the bmp image is upside down */ if ( SDL_RWseek(src, fp_offset+bfOffBits, SEEK_SET) < 0 ) { SDL_Error(SDL_EFSEEK); was_error = 1; goto done; } bits = (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; } while ( bits > (Uint8 *)surface->pixels ) { bits -= surface->pitch; 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 = 1; 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 = 1; 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); } } } done: if ( was_error ) { if ( surface ) { SDL_FreeSurface(surface); } surface = NULL; } if ( freesrc && src ) { SDL_RWclose(src); } return(surface); }
/** * @brief Makes sure parameters work properly. Local helper function. * * \sa * http://wiki.libsdl.org/moin.cgi/SDL_RWseek * http://wiki.libsdl.org/moin.cgi/SDL_RWread */ void _testGenericRWopsValidations(SDL_RWops *rw, int write) { char buf[sizeof(RWopsHelloWorldTestString)]; Sint64 i; size_t s; int seekPos = SDLTest_RandomIntegerInRange(4, 8); /* Clear buffer */ SDL_zero(buf); /* Set to start. */ i = SDL_RWseek(rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); /* Test write. */ s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1, 1); SDLTest_AssertPass("Call to SDL_RWwrite succeeded"); if (write) { SDLTest_AssertCheck(s == (size_t)1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", s); } else { SDLTest_AssertCheck(s == (size_t)0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", s); } /* Test seek to random position */ i = SDL_RWseek( rw, seekPos, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)seekPos, "Verify seek to %i with SDL_RWseek (RW_SEEK_SET), expected %i, got %"SDL_PRIs64, seekPos, seekPos, i); /* Test seek back to start */ i = SDL_RWseek(rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); /* Test read */ s = SDL_RWread( rw, buf, 1, sizeof(RWopsHelloWorldTestString)-1 ); SDLTest_AssertPass("Call to SDL_RWread succeeded"); SDLTest_AssertCheck( s == (size_t)(sizeof(RWopsHelloWorldTestString)-1), "Verify result from SDL_RWread, expected %i, got %i", sizeof(RWopsHelloWorldTestString)-1, s); SDLTest_AssertCheck( SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1 ) == 0, "Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf); /* More seek tests. */ i = SDL_RWseek( rw, -4, RW_SEEK_CUR ); SDLTest_AssertPass("Call to SDL_RWseek(...,-4,RW_SEEK_CUR) succeeded"); SDLTest_AssertCheck( i == (Sint64)(sizeof(RWopsHelloWorldTestString)-5), "Verify seek to -4 with SDL_RWseek (RW_SEEK_CUR), expected %i, got %"SDL_PRIs64, sizeof(RWopsHelloWorldTestString)-5, i); i = SDL_RWseek( rw, -1, RW_SEEK_END ); SDLTest_AssertPass("Call to SDL_RWseek(...,-1,RW_SEEK_END) succeeded"); SDLTest_AssertCheck( i == (Sint64)(sizeof(RWopsHelloWorldTestString)-2), "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %"SDL_PRIs64, sizeof(RWopsHelloWorldTestString)-2, i); /* Invalid whence seek */ i = SDL_RWseek( rw, 0, 999 ); SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded"); SDLTest_AssertCheck( i == (Sint64)(-1), "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %"SDL_PRIs64, i); }
static int ov_close_func_nofreesrc(void *datasource) { return SDL_RWseek((SDL_RWops*)datasource, 0, RW_SEEK_SET); }
static int sdl_seek_func ( int pos, void *appdata ) { assert ( pos >= 0 ); assert ( appdata ); return SDL_RWseek ( ( SDL_RWops * ) appdata, pos, SEEK_SET ); }
static int ovpack_seek( void *datasource, ogg_int64_t offset, int whence ) { SDL_RWops *rw = datasource; return SDL_RWseek( rw, offset, whence ); }
static long ovpack_tell( void *datasource ) { SDL_RWops *rw = datasource; return SDL_RWseek( rw, 0, SEEK_CUR ); }
/* See if an image is contained in a data source */ int IMG_isJPG(SDL_RWops *src) { 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); }
SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src) { Sint64 start; const char *error = NULL; SDL_Surface *volatile surface = NULL; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; WebPBitstreamFeatures features; int raw_data_size; uint8_t *raw_data = NULL; int r; uint8_t *ret; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( !IMG_Init(IMG_INIT_WEBP) ) { goto error; } raw_data_size = -1; if ( !webp_getinfo( src, &raw_data_size ) ) { error = "Invalid WEBP"; goto error; } // seek to start of file SDL_RWseek(src, 0, RW_SEEK_SET ); raw_data = (uint8_t*) SDL_malloc( raw_data_size ); if ( raw_data == NULL ) { error = "Failed to allocate enought buffer for WEBP"; goto error; } r = SDL_RWread(src, raw_data, 1, raw_data_size ); if ( r != raw_data_size ) { error = "Failed to read WEBP"; goto error; } #if 0 // extract size of picture, not interesting since we don't know about alpha channel int width = -1, height = -1; if ( !WebPGetInfo( raw_data, raw_data_size, &width, &height ) ) { printf("WebPGetInfo has failed\n" ); return NULL; } #endif if ( lib.webp_get_features_internal( raw_data, raw_data_size, &features, WEBP_DECODER_ABI_VERSION ) != VP8_STATUS_OK ) { error = "WebPGetFeatures has failed"; goto error; } /* Check if it's ok !*/ #if SDL_BYTEORDER == SDL_LIL_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = (features.has_alpha) ? 0xFF000000 : 0; #else s = (features.has_alpha) ? 0 : 8; Rmask = 0xFF000000 >> s; Gmask = 0x00FF0000 >> s; Bmask = 0x0000FF00 >> s; Amask = 0x000000FF >> s; #endif surface = SDL_CreateRGBSurface(SDL_SWSURFACE, features.width, features.height, features.has_alpha?32:24, Rmask,Gmask,Bmask,Amask); if ( surface == NULL ) { error = "Failed to allocate SDL_Surface"; goto error; } if ( features.has_alpha ) { ret = lib.webp_decode_rgba_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h, surface->pitch ); } else { ret = lib.webp_decode_rgb_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h, surface->pitch ); } if ( !ret ) { error = "Failed to decode WEBP"; goto error; } return surface; error: if ( surface ) { SDL_FreeSurface( surface ); } if ( raw_data ) { SDL_free( raw_data ); } if ( error ) { IMG_SetError( error ); } SDL_RWseek(src, start, RW_SEEK_SET); return(NULL); }
/* Load a wave file */ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc) { Uint32 magic; Mix_Chunk *chunk; SDL_AudioSpec wavespec, *loaded; SDL_AudioCVT wavecvt; int samplesize; /* rcg06012001 Make sure src is valid */ if ( ! src ) { SDL_SetError("Mix_LoadWAV_RW with NULL src"); return(NULL); } /* Make sure audio has been opened */ if ( ! audio_opened ) { SDL_SetError("Audio device hasn't been opened"); if ( freesrc && src ) { SDL_RWclose(src); } return(NULL); } /* Allocate the chunk memory */ chunk = (Mix_Chunk *)malloc(sizeof(Mix_Chunk)); if ( chunk == NULL ) { SDL_SetError("Out of memory"); if ( freesrc ) { SDL_RWclose(src); } return(NULL); } /* Find out what kind of audio file this is */ magic = SDL_ReadLE32(src); /* Seek backwards for compatibility with older loaders */ SDL_RWseek(src, -(int)sizeof(Uint32), RW_SEEK_CUR); switch (magic) { case WAVE: case RIFF: loaded = SDL_LoadWAV_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; #ifdef OGG_MUSIC case OGGS: loaded = Mix_LoadOGG_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; #endif default: SDL_SetError("Unrecognized sound file type"); return(0); } if ( !loaded ) { free(chunk); return(NULL); } #if 0 PrintFormat("Audio device", &mixer); PrintFormat("-- Wave file", &wavespec); #endif /* Build the audio converter and create conversion buffers */ if ( SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq, mixer.format, mixer.channels, mixer.freq) < 0 ) { SDL_FreeWAV(chunk->abuf); free(chunk); return(NULL); } samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels; wavecvt.len = chunk->alen & ~(samplesize-1); wavecvt.buf = (Uint8 *)malloc(wavecvt.len*wavecvt.len_mult); if ( wavecvt.buf == NULL ) { SDL_SetError("Out of memory"); SDL_FreeWAV(chunk->abuf); free(chunk); return(NULL); } memcpy(wavecvt.buf, chunk->abuf, chunk->alen); SDL_FreeWAV(chunk->abuf); /* Run the audio converter */ if ( SDL_ConvertAudio(&wavecvt) < 0 ) { free(wavecvt.buf); free(chunk); return(NULL); } chunk->allocated = 1; chunk->abuf = wavecvt.buf; chunk->alen = wavecvt.len_cvt; chunk->volume = MIX_MAX_VOLUME; return(chunk); }
static int MPGLIB_open(Sound_Sample *sample, const char *ext) { Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; mpglib_t *mpg = NULL; int rc; /* * If I understand things correctly, MP3 files don't really have any * magic header we can check for. The MP3 player is expected to just * pick the first thing that looks like a valid frame and start * playing from there. * * So here's what we do: If the caller insists that this is really * MP3 we'll take his word for it. Otherwise, use the same test as * SDL_mixer does and check if the stream starts with something that * looks like a frame. * * A frame begins with 11 bits of frame sync (all bits must be set), * followed by a two-bit MPEG Audio version ID: * * 00 - MPEG Version 2.5 (later extension of MPEG 2) * 01 - reserved * 10 - MPEG Version 2 (ISO/IEC 13818-3) * 11 - MPEG Version 1 (ISO/IEC 11172-3) * * Apparently we don't handle MPEG Version 2.5. */ if (__Sound_strcasecmp(ext, "MP3") != 0) { Uint8 mp3_magic[2]; if (SDL_RWread(internal->rw, mp3_magic, sizeof (mp3_magic), 1) != 1) BAIL_MACRO("MPGLIB: Could not read MP3 magic.", 0); if (mp3_magic[0] != 0xFF || (mp3_magic[1] & 0xF0) != 0xF0) BAIL_MACRO("MPGLIB: Not an MP3 stream.", 0); /* If the seek fails, we'll probably miss a frame, but oh well. */ SDL_RWseek(internal->rw, -sizeof (mp3_magic), SEEK_CUR); } /* if */ mpg = (mpglib_t *) malloc(sizeof (mpglib_t)); BAIL_IF_MACRO(mpg == NULL, ERR_OUT_OF_MEMORY, 0); memset(mpg, '\0', sizeof (mpglib_t)); InitMP3(&mpg->mp); rc = SDL_RWread(internal->rw, mpg->inbuf, 1, sizeof (mpg->inbuf)); if (rc <= 0) { free(mpg); BAIL_MACRO("MPGLIB: Failed to read any data at all", 0); } /* if */ if (decodeMP3(&mpg->mp, mpg->inbuf, rc, mpg->outbuf, sizeof (mpg->outbuf), &mpg->outleft) == MP3_ERR) { free(mpg); BAIL_MACRO("MPGLIB: Not an MP3 stream?", 0); } /* if */ SNDDBG(("MPGLIB: Accepting data stream.\n")); internal->decoder_private = mpg; sample->actual.rate = mpglib_freqs[mpg->mp.fr.sampling_frequency]; sample->actual.channels = mpg->mp.fr.stereo; sample->actual.format = AUDIO_S16SYS; sample->flags = SOUND_SAMPLEFLAG_NONE; return(1); /* we'll handle this data. */ } /* MPGLIB_open */
static int sdl_seek_to_end_func ( void *appdata ) { assert ( appdata ); return SDL_RWseek ( ( SDL_RWops * ) appdata, 0, SEEK_END ); }
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 ) { if ( saveme->format->palette ) { 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_Rect bounds; /* Convert to 24 bits per pixel */ surface = SDL_CreateRGBSurface(SDL_SWSURFACE, saveme->w, saveme->h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x00FF0000, 0x0000FF00, 0x000000FF, #else 0x000000FF, 0x0000FF00, 0x00FF0000, #endif 0); if ( surface != NULL ) { bounds.x = 0; bounds.y = 0; bounds.w = saveme->w; bounds.h = saveme->h; if ( SDL_LowerBlit(saveme, &bounds, surface, &bounds) < 0 ) { SDL_FreeSurface(surface); SDL_SetError( "Couldn't convert image to 24 bpp"); surface = NULL; } } } } if ( surface && (SDL_LockSurface(surface) == 0) ) { /* 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, SEEK_SET) < 0 ) { SDL_Error(SDL_EFSEEK); } SDL_WriteLE32(dst, bfOffBits); if ( SDL_RWseek(dst, fp_offset+bfOffBits, SEEK_SET) < 0 ) { SDL_Error(SDL_EFSEEK); } /* Write the bitmap image upside down */ bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); pad = ((surface->pitch%4) ? (4-(surface->pitch%4)) : 0); while ( bits > (Uint8 *)surface->pixels ) { bits -= surface->pitch; if ( SDL_RWwrite(dst, bits, 1, surface->pitch) != surface->pitch) { 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, SEEK_SET) < 0 ) { SDL_Error(SDL_EFSEEK); } SDL_WriteLE32(dst, bfSize); if ( SDL_RWseek(dst, fp_offset+bfSize, 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((strcmp(SDL_GetError(), "") == 0) ? 0 : -1); }
int net_http_upload(const char* filename, char* fmt, ...) { va_list args; va_start(args, fmt); vsnprintf(url_buffer, 500, fmt, args); va_end(args); int parts = sscanf(url_buffer, "http://%[^/]%s", host_buffer, path_buffer); if (parts != 2) { warning("Couldn't resolve parts of URL '%s'", url_buffer); return HTTP_ERR_URL; } IPaddress ip; if ( SDLNet_ResolveHost(&ip, host_buffer, 80) == -1) { warning("Couldn't Resolve Host: %s", SDLNet_GetError()); return HTTP_ERR_HOST; } TCPsocket sock = SDLNet_TCP_Open(&ip); if (!sock) { warning("Couldn't open socket: %s", SDLNet_GetError()); return HTTP_ERR_SOCKET; } SDL_RWops* file = SDL_RWFromFile(filename, "r"); if (file == NULL) { warning("Couldn't Open File '%s' to upload", filename); return HTTP_ERR_NOFILE; } size_t size = SDL_RWseek(file,0,SEEK_END); char* contents = malloc(size+1); contents[size] = '\0'; SDL_RWseek(file, 0, SEEK_SET); SDL_RWread(file, contents, size, 1); SDL_RWclose(file); char sockbody[size + 1024 * 4]; char sockheaders[1024*4]; snprintf(sockbody,((size + 1024 * 4) - 1), "--CorangeUploadBoundary\r\n" "content-disposition: form-data; name=\"corangeupload\"; filename=\"%s\"\r\n" "Content-Type: text/plain\r\n" "\r\n" "%s\r\n" "--CorangeUploadBoundary--\r\n" "\r\n", filename, contents); snprintf(sockheaders,((1024 * 4) - 1), "POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Length: %i\r\n" "Content-Type: multipart/form-data; boundary=CorangeUploadBoundary\r\n" "\r\n" , path_buffer, host_buffer, (int)strlen(sockbody)); int result = 0; result = SDLNet_TCP_Send(sock, sockheaders, strlen(sockheaders)); if (result < strlen(sockheaders)) { warning("Error sending http request: %s", SDLNet_GetError()); return HTTP_ERR_DATA; } result = SDLNet_TCP_Send(sock, sockbody, strlen(sockbody)); if (result < strlen(sockbody)) { warning("Error sending http request: %s", SDLNet_GetError()); return HTTP_ERR_DATA; } char line[1024]; while (SDLNet_TCP_RecvLine(sock, line, 1023)) { //debug("Recived: %s", line); } return HTTP_ERR_NONE; }
/** * @brief Tests writing and reading from file using endian aware functions. * * \sa * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile * http://wiki.libsdl.org/moin.cgi/SDL_RWClose * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16 * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16 */ int rwops_testFileWriteReadEndian(void) { SDL_RWops *rw; Sint64 result; int mode; size_t objectsWritten; Uint16 BE16value; Uint32 BE32value; Uint64 BE64value; Uint16 LE16value; Uint32 LE32value; Uint64 LE64value; Uint16 BE16test; Uint32 BE32test; Uint64 BE64test; Uint16 LE16test; Uint32 LE32test; Uint64 LE64test; int cresult; for (mode = 0; mode < 3; mode++) { /* Create test data */ switch (mode) { case 0: SDLTest_Log("All 0 values"); BE16value = 0; BE32value = 0; BE64value = 0; LE16value = 0; LE32value = 0; LE64value = 0; break; case 1: SDLTest_Log("All 1 values"); BE16value = 1; BE32value = 1; BE64value = 1; LE16value = 1; LE32value = 1; LE64value = 1; break; case 2: SDLTest_Log("Random values"); BE16value = SDLTest_RandomUint16(); BE32value = SDLTest_RandomUint32(); BE64value = SDLTest_RandomUint64(); LE16value = SDLTest_RandomUint16(); LE32value = SDLTest_RandomUint32(); LE64value = SDLTest_RandomUint64(); break; } /* Write test. */ rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")"); SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); /* Bail out if NULL */ if (rw == NULL) return TEST_ABORTED; /* Write test data */ objectsWritten = SDL_WriteBE16(rw, BE16value); SDLTest_AssertPass("Call to SDL_WriteBE16()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE32(rw, BE32value); SDLTest_AssertPass("Call to SDL_WriteBE32()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE64(rw, BE64value); SDLTest_AssertPass("Call to SDL_WriteBE64()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE16(rw, LE16value); SDLTest_AssertPass("Call to SDL_WriteLE16()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE32(rw, LE32value); SDLTest_AssertPass("Call to SDL_WriteLE32()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE64(rw, LE64value); SDLTest_AssertPass("Call to SDL_WriteLE64()"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); /* Test seek to start */ result = SDL_RWseek( rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %"SDL_PRIs64, result); /* Read test data */ BE16test = SDL_ReadBE16(rw); SDLTest_AssertPass("Call to SDL_ReadBE16()"); SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test); BE32test = SDL_ReadBE32(rw); SDLTest_AssertPass("Call to SDL_ReadBE32()"); SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test); BE64test = SDL_ReadBE64(rw); SDLTest_AssertPass("Call to SDL_ReadBE64()"); SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, BE64value, BE64test); LE16test = SDL_ReadLE16(rw); SDLTest_AssertPass("Call to SDL_ReadLE16()"); SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test); LE32test = SDL_ReadLE32(rw); SDLTest_AssertPass("Call to SDL_ReadLE32()"); SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test); LE64test = SDL_ReadLE64(rw); SDLTest_AssertPass("Call to SDL_ReadLE64()"); SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, LE64value, LE64test); /* Close handle */ cresult = SDL_RWclose(rw); SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult); } return TEST_COMPLETED; }
void JE_loadConfiguration( void ) { SDL_RWops *fi; int z; JE_byte *p; int y; fi = dir_fopen_warn(get_user_directory(), "tyrian.cfg", "rb"); if (fi && ftell_eof(fi) == 20 + sizeof(keySettings)) { /* SYN: I've hardcoded the sizes here because the .CFG file format is fixed anyways, so it's not like they'll change. */ background2 = 0; efread(fi, &background2, 1, 1); efread(fi, &gameSpeed, 1, 1); efread(fi, &inputDevice_, 1, 1); efread(fi, &jConfigure, 1, 1); efread(fi, &versionNum, 1, 1); efread(fi, &processorType, 1, 1); efread(fi, &midiPort, 1, 1); efread(fi, &soundEffects, 1, 1); efread(fi, &gammaCorrection, 1, 1); efread(fi, &difficultyLevel, 1, 1); efread(fi, joyButtonAssign, 1, 4); efread(fi, &tyrMusicVolume, 2, 1); efread(fi, &fxVolume, 2, 1); efread(fi, inputDevice, 1, 2); efread(fi, keySettings, sizeof(*keySettings), COUNTOF(keySettings)); SDL_RWclose(fi); } else { printf("\nInvalid or missing TYRIAN.CFG! Continuing using defaults.\n\n"); soundEffects = 1; memcpy(&keySettings, &defaultKeySettings, sizeof(keySettings)); background2 = true; tyrMusicVolume = fxVolume = 128; gammaCorrection = 0; processorType = 3; gameSpeed = 4; } load_opentyrian_config(); if (tyrMusicVolume > 255) tyrMusicVolume = 255; if (fxVolume > 255) fxVolume = 255; JE_calcFXVol(); set_volume(tyrMusicVolume, fxVolume); fi = dir_fopen_warn(get_user_directory(), "tyrian.sav", "rb"); if (fi) { SDL_RWseek(fi, 0, SEEK_SET); efread(fi, saveTemp, 1, sizeof(saveTemp)); JE_decryptSaveTemp(); /* SYN: The original mostly blasted the save file into raw memory. However, our lives are not so easy, because the C struct is necessarily a different size. So instead we have to loop through each record and load fields manually. *emo tear* :'( */ p = saveTemp; for (z = 0; z < SAVE_FILES_NUM; z++) { memcpy(&saveFiles[z].encode, p, sizeof(JE_word)); p += 2; saveFiles[z].encode = SDL_SwapLE16(saveFiles[z].encode); memcpy(&saveFiles[z].level, p, sizeof(JE_word)); p += 2; saveFiles[z].level = SDL_SwapLE16(saveFiles[z].level); memcpy(&saveFiles[z].items, p, sizeof(JE_PItemsType)); p += sizeof(JE_PItemsType); memcpy(&saveFiles[z].score, p, sizeof(JE_longint)); p += 4; saveFiles[z].score = SDL_SwapLE32(saveFiles[z].score); memcpy(&saveFiles[z].score2, p, sizeof(JE_longint)); p += 4; saveFiles[z].score2 = SDL_SwapLE32(saveFiles[z].score2); /* SYN: Pascal strings are prefixed by a byte holding the length! */ memset(&saveFiles[z].levelName, 0, sizeof(saveFiles[z].levelName)); memcpy(&saveFiles[z].levelName, &p[1], *p); p += 10; /* This was a BYTE array, not a STRING, in the original. Go fig. */ memcpy(&saveFiles[z].name, p, 14); p += 14; memcpy(&saveFiles[z].cubes, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].power, p, sizeof(JE_byte) * 2); p += 2; memcpy(&saveFiles[z].episode, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].lastItems, p, sizeof(JE_PItemsType)); p += sizeof(JE_PItemsType); memcpy(&saveFiles[z].difficulty, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].secretHint, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].input1, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].input2, p, sizeof(JE_byte)); p++; /* booleans were 1 byte in pascal -- working around it */ Uint8 temp; memcpy(&temp, p, 1); p++; saveFiles[z].gameHasRepeated = temp != 0; memcpy(&saveFiles[z].initialDifficulty, p, sizeof(JE_byte)); p++; memcpy(&saveFiles[z].highScore1, p, sizeof(JE_longint)); p += 4; saveFiles[z].highScore1 = SDL_SwapLE32(saveFiles[z].highScore1); memcpy(&saveFiles[z].highScore2, p, sizeof(JE_longint)); p += 4; saveFiles[z].highScore2 = SDL_SwapLE32(saveFiles[z].highScore2); memset(&saveFiles[z].highScoreName, 0, sizeof(saveFiles[z].highScoreName)); memcpy(&saveFiles[z].highScoreName, &p[1], *p); p += 30; memcpy(&saveFiles[z].highScoreDiff, p, sizeof(JE_byte)); p++; } /* SYN: This is truncating to bytes. I have no idea what this is doing or why. */ /* TODO: Figure out what this is about and make sure it isn't broked. */ editorLevel = (saveTemp[SIZEOF_SAVEGAMETEMP - 5] << 8) | saveTemp[SIZEOF_SAVEGAMETEMP - 6]; SDL_RWclose(fi); } else { /* We didn't have a save file! Let's make up random stuff! */ editorLevel = 800; for (z = 0; z < 100; z++) { saveTemp[SAVE_FILES_SIZE + z] = initialItemAvail[z]; } for (z = 0; z < SAVE_FILES_NUM; z++) { saveFiles[z].level = 0; for (y = 0; y < 14; y++) { saveFiles[z].name[y] = ' '; } saveFiles[z].name[14] = 0; saveFiles[z].highScore1 = ((mt_rand() % 20) + 1) * 1000; if (z % 6 > 2) { saveFiles[z].highScore2 = ((mt_rand() % 20) + 1) * 1000; strcpy(saveFiles[z].highScoreName, defaultTeamNames[mt_rand() % 22]); } else { strcpy(saveFiles[z].highScoreName, defaultHighScoreNames[mt_rand() % 34]); } } } JE_initProcessorType(); }
bool SDLFileInputStream::open( const FilePath & _folder, const FilePath & _fileName, size_t _offset, size_t _size ) { STDEX_THREAD_GUARD_SCOPE( this, "SDLFileInputStream::open" ); # ifdef _DEBUG m_folder = _folder.c_str(); m_fileName = _fileName.c_str(); # endif Char filePath[MENGINE_MAX_PATH]; if( this->openFile_( _folder, _fileName, filePath ) == false ) { return false; } Sint64 size = SDL_RWsize(m_rwops); if( 0 > size ) { this->close_(); LOGGER_ERROR(m_serviceProvider)("SDLFileInputStream::open %s invalid file size" , filePath ); return false; } if( _offset + _size > size ) { LOGGER_ERROR(m_serviceProvider)("SDLFileInputStream::open %s invalid file range %d:%d size %d" , filePath , _offset , _size , size ); return false; } m_size = _size == 0 ? (size_t)size : _size; m_offset = _offset; m_carriage = 0; m_capacity = 0; m_reading = 0; if( m_offset != 0 ) { Sint64 result = SDL_RWseek( m_rwops, static_cast<Sint64>(m_offset), RW_SEEK_SET ); if( 0 > result ) { const char* sdlError = SDL_GetError(); LOGGER_ERROR( m_serviceProvider )("Win32InputStream::open seek offset %d size %d get error %s" , m_offset , m_size , sdlError ); return false; } } return true; }
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc) { Mix_Music *music; if (!rw) { Mix_SetError("RWops pointer is NULL"); return NULL; } /* If the caller wants auto-detection, figure out what kind of file * this is. */ if (type == MUS_NONE) { if ((type = detect_music_type(rw)) == MUS_NONE) { /* Don't call Mix_SetError() here since detect_music_type() * does that. */ return NULL; } } /* Allocate memory for the music structure */ music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music)); if (music == NULL ) { Mix_SetError("Out of memory"); return NULL; } music->error = 0; switch (type) { #ifdef WAV_MUSIC case MUS_WAV: /* The WAVE loader needs the first 4 bytes of the header */ { Uint8 magic[5]; int start = SDL_RWtell(rw); if (SDL_RWread(rw, magic, 1, 4) != 4) { Mix_SetError("Couldn't read from RWops"); return MUS_NONE; } SDL_RWseek(rw, start, RW_SEEK_SET); magic[4] = '\0'; music->type = MUS_WAV; music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc); } if (music->data.wave == NULL) { music->error = 1; } break; #endif #ifdef OGG_MUSIC case MUS_OGG: music->type = MUS_OGG; music->data.ogg = OGG_new_RW(rw, freesrc); if ( music->data.ogg == NULL ) { music->error = 1; } break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: music->type = MUS_FLAC; music->data.flac = FLAC_new_RW(rw, freesrc); if ( music->data.flac == NULL ) { music->error = 1; } break; #endif #ifdef MP3_MUSIC case MUS_MP3: if ( Mix_Init(MIX_INIT_MP3) ) { SMPEG_Info info; music->type = MUS_MP3; music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0); if ( !info.has_audio ) { Mix_SetError("MPEG file does not have any audio stream."); music->error = 1; } else { smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer); } } else { music->error = 1; } break; #elif defined(MP3_MAD_MUSIC) case MUS_MP3: music->type = MUS_MP3_MAD; music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc); if (music->data.mp3_mad == 0) { Mix_SetError("Could not initialize MPEG stream."); music->error = 1; } break; #endif #ifdef MID_MUSIC case MUS_MID: music->type = MUS_MID; #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc); if ( music->data.nativemidi == NULL ) { Mix_SetError("%s", native_midi_error()); music->error = 1; } break; } #endif #ifdef USE_FLUIDSYNTH_MIDI if ( fluidsynth_ok ) { music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc); if ( music->data.fluidsynthmidi == NULL ) { music->error = 1; } break; } #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { music->data.midi = Timidity_LoadSong_RW(rw, freesrc); if ( music->data.midi == NULL ) { Mix_SetError("%s", Timidity_Error()); music->error = 1; } } else { Mix_SetError("%s", Timidity_Error()); music->error = 1; } #endif break; #endif #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC) case MUS_MOD: music->error = 1; #ifdef MODPLUG_MUSIC if ( music->error ) { music->type = MUS_MODPLUG; music->data.modplug = modplug_new_RW(rw, freesrc); if ( music->data.modplug ) { music->error = 0; } } #endif #ifdef MOD_MUSIC if ( music->error ) { music->type = MUS_MOD; music->data.module = MOD_new_RW(rw, freesrc); if ( music->data.module ) { music->error = 0; } } #endif break; #endif default: Mix_SetError("Unrecognized music format"); music->error=1; } /* switch (want) */ if (music->error) { SDL_free(music); music=NULL; } return(music); }
int IMG_LoadPNG_RW(SDL_RWops *src, IMG_File* dst) { int start; const char *error; SDL_Surface *volatile surface; png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; SDL_Palette *palette; png_bytep *volatile row_pointers; int row, i; volatile int ckey = -1; png_color_16 *transv; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return 0; } start = SDL_RWtell(src); if ( IMG_InitPNG() < 0 ) { return 0; } /* Initialize the data we will clean up when we're done */ error = NULL; png_ptr = NULL; info_ptr = NULL; row_pointers = NULL; surface = NULL; /* Create the PNG loading context structure */ png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL); if (png_ptr == NULL){ error = "Couldn't allocate memory for PNG file or incompatible PNG dll"; goto done; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = lib.png_create_info_struct(png_ptr); if (info_ptr == NULL) { error = "Couldn't create image information for PNG file"; goto done; } /* Set error handling if you are using setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in png_create_read_struct() earlier. */ if ( setjmp(png_ptr->jmpbuf) ) { error = "Error reading the PNG file."; goto done; } /* Set up the input control */ lib.png_set_read_fn(png_ptr, src, png_read_data); /* Read PNG header info */ lib.png_read_info(png_ptr, info_ptr); lib.png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* tell libpng to strip 16 bit/color files down to 8 bits/color */ lib.png_set_strip_16(png_ptr) ; /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single * byte into separate bytes (useful for paletted and grayscale images). */ lib.png_set_packing(png_ptr); /* scale greyscale values to the range 0..255 */ if(color_type == PNG_COLOR_TYPE_GRAY) lib.png_set_expand(png_ptr); /* For images with a single "transparent colour", set colour key; if more than one index has transparency, or if partially transparent entries exist, use full alpha channel */ if (lib.png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { int num_trans; Uint8 *trans; lib.png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &transv); if(color_type == PNG_COLOR_TYPE_PALETTE) { /* Check if all tRNS entries are opaque except one */ int i, t = -1; for(i = 0; i < num_trans; i++) if(trans[i] == 0) { if(t >= 0) break; t = i; } else if(trans[i] != 255) break; if(i == num_trans) { /* exactly one transparent index */ ckey = t; } else { /* more than one transparent index, or translucency */ lib.png_set_expand(png_ptr); } } else ckey = 0; /* actual value will be set later */ } if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) lib.png_set_gray_to_rgb(png_ptr); lib.png_read_update_info(png_ptr, info_ptr); lib.png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); /* Allocate the SDL surface to hold the image */ Rmask = Gmask = Bmask = Amask = 0 ; if ( color_type != PNG_COLOR_TYPE_PALETTE ) { if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0; } else { int s = (info_ptr->channels == 4) ? 0 : 8; Rmask = 0xFF000000 >> s; Gmask = 0x00FF0000 >> s; Bmask = 0x0000FF00 >> s; Amask = 0x000000FF >> s; } } surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, bit_depth*info_ptr->channels, Rmask,Gmask,Bmask,Amask); if ( surface == NULL ) { error = "Out of memory"; goto done; } if(ckey != -1) { if(color_type != PNG_COLOR_TYPE_PALETTE) /* FIXME: Should these be truncated or shifted down? */ ckey = SDL_MapRGB(surface->format, (Uint8)transv->red, (Uint8)transv->green, (Uint8)transv->blue); SDL_SetColorKey(surface, SDL_SRCCOLORKEY, ckey); } /* Create the array of pointers to image data */ row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*height); if ( (row_pointers == NULL) ) { error = "Out of memory"; goto done; } for (row = 0; row < (int)height; row++) { row_pointers[row] = (png_bytep) (Uint8 *)surface->pixels + row*surface->pitch; } /* Read the entire image in one go */ lib.png_read_image(png_ptr, row_pointers); /* and we're done! (png_read_end() can be omitted if no processing of * post-IDAT text/time/etc. is desired) * In some cases it can't read PNG's created by some popular programs (ACDSEE), * we do not want to process comments, so we omit png_read_end lib.png_read_end(png_ptr, info_ptr); */ /* Load the palette, if any */ palette = surface->format->palette; if ( palette ) { if(color_type == PNG_COLOR_TYPE_GRAY) { palette->ncolors = 256; for(i = 0; i < 256; i++) { palette->colors[i].r = i; palette->colors[i].g = i; palette->colors[i].b = i; } } else if (info_ptr->num_palette > 0 ) { palette->ncolors = info_ptr->num_palette; for( i=0; i<info_ptr->num_palette; ++i ) { palette->colors[i].b = info_ptr->palette[i].blue; palette->colors[i].g = info_ptr->palette[i].green; palette->colors[i].r = info_ptr->palette[i].red; } } } done: /* Clean up and return */ if ( png_ptr ) { lib.png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : (png_infopp)0, (png_infopp)0); } if ( row_pointers ) { free(row_pointers); } if ( error ) { SDL_RWseek(src, start, SEEK_SET); if ( surface ) { SDL_FreeSurface(surface); surface = NULL; } IMG_QuitPNG(); IMG_SetError(error); } else { IMG_QuitPNG(); } dst->format = IMG_FORMAT_PNG; return IMG_SurfaceToFrameset(surface, dst); }
int seek(int offset, int whence) { return SDL_RWseek(rwops_, offset, whence); }
/* Load a wave file */ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc) { Uint32 magic; Mix_Chunk *chunk; SDL_AudioSpec wavespec, *loaded; SDL_AudioCVT wavecvt; int samplesize; /* rcg06012001 Make sure src is valid */ if ( ! src ) { SDL_SetError("Mix_LoadWAV_RW with NULL src"); return(NULL); } /* Make sure audio has been opened */ if ( ! audio_opened ) { SDL_SetError("Audio device hasn't been opened"); if ( freesrc ) { SDL_RWclose(src); } return(NULL); } /* Allocate the chunk memory */ chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk)); if ( chunk == NULL ) { SDL_SetError("Out of memory"); if ( freesrc ) { SDL_RWclose(src); } return(NULL); } /* Find out what kind of audio file this is */ magic = SDL_ReadLE32(src); /* Seek backwards for compatibility with older loaders */ SDL_RWseek(src, -(int)sizeof(Uint32), RW_SEEK_CUR); switch (magic) { case WAVE: case RIFF: loaded = SDL_LoadWAV_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; case FORM: loaded = Mix_LoadAIFF_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; #ifdef OGG_MUSIC case OGGS: loaded = Mix_LoadOGG_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; #endif #ifdef FLAC_MUSIC case FLAC: loaded = Mix_LoadFLAC_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; #endif case CREA: loaded = Mix_LoadVOC_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; default: #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC) if (detect_mp3((Uint8*)&magic)) { /* note: send a copy of the mixer spec */ wavespec = mixer; loaded = Mix_LoadMP3_RW(src, freesrc, &wavespec, (Uint8 **)&chunk->abuf, &chunk->alen); break; } #endif SDL_SetError("Unrecognized sound file type"); if ( freesrc ) { SDL_RWclose(src); } loaded = NULL; break; } if ( !loaded ) { /* The individual loaders have closed src if needed */ SDL_free(chunk); return(NULL); } #if 0 PrintFormat("Audio device", &mixer); PrintFormat("-- Wave file", &wavespec); #endif /* Build the audio converter and create conversion buffers */ if ( wavespec.format != mixer.format || wavespec.channels != mixer.channels || wavespec.freq != mixer.freq ) { if ( SDL_BuildAudioCVT(&wavecvt, wavespec.format, wavespec.channels, wavespec.freq, mixer.format, mixer.channels, mixer.freq) < 0 ) { SDL_free(chunk->abuf); SDL_free(chunk); return(NULL); } samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels; wavecvt.len = chunk->alen & ~(samplesize-1); wavecvt.buf = (Uint8 *)SDL_calloc(1, wavecvt.len*wavecvt.len_mult); if ( wavecvt.buf == NULL ) { SDL_SetError("Out of memory"); SDL_free(chunk->abuf); SDL_free(chunk); return(NULL); } SDL_memcpy(wavecvt.buf, chunk->abuf, chunk->alen); SDL_free(chunk->abuf); /* Run the audio converter */ if ( SDL_ConvertAudio(&wavecvt) < 0 ) { SDL_free(wavecvt.buf); SDL_free(chunk); return(NULL); } chunk->abuf = wavecvt.buf; chunk->alen = wavecvt.len_cvt; } chunk->allocated = 1; chunk->volume = MIX_MAX_VOLUME; return(chunk); }
SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) { SDL_Surface *Image; Uint8 id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk; Uint32 size, bytesloaded, nbcolors; Uint32 i, j, bytesperline, nbplanes, 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; } 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, 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; } if ( bmhd.mask & 1 ) ++nbplanes; /* There is a mask ( 'stencil' ) */ /* Allocate memory for a temporary buffer ( used for decompression/deinterleaving ) */ if ( ( MiniBuf = (void *)malloc( bytesperline * nbplanes ) ) == 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 ) { int nbrcolorsfinal = 1 << nbplanes; 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; } 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; 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 ( !SDL_RWread( src, &color, 1, 1 ) ) { error="error reading BODY chunk"; goto done; } memset( ptr, color, count ); } else { ++count; if ( !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; 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 {
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc) { Mix_Music *music; Sint64 start; if (!src) { Mix_SetError("RWops pointer is NULL"); return NULL; } start = SDL_RWtell(src); /* If the caller wants auto-detection, figure out what kind of file * this is. */ if (type == MUS_NONE) { if ((type = detect_music_type(src)) == MUS_NONE) { /* Don't call Mix_SetError() here since detect_music_type() * does that. */ if (freesrc) { SDL_RWclose(src); } return NULL; } } /* Allocate memory for the music structure */ music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music)); if (music == NULL ) { Mix_SetError("Out of memory"); if (freesrc) { SDL_RWclose(src); } return NULL; } music->error = 1; switch (type) { #ifdef WAV_MUSIC case MUS_WAV: music->type = MUS_WAV; music->data.wave = WAVStream_LoadSong_RW(src, freesrc); if (music->data.wave) { music->error = 0; } break; #endif #ifdef OGG_MUSIC case MUS_OGG: music->type = MUS_OGG; music->data.ogg = OGG_new_RW(src, freesrc); if (music->data.ogg) { music->error = 0; } break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: music->type = MUS_FLAC; music->data.flac = FLAC_new_RW(src, freesrc); if (music->data.flac) { music->error = 0; } break; #endif #ifdef MP3_MUSIC case MUS_MP3: if (Mix_Init(MIX_INIT_MP3)) { SMPEG_Info info; music->type = MUS_MP3; music->data.mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0); if (!info.has_audio) { Mix_SetError("MPEG file does not have any audio stream."); smpeg.SMPEG_delete(music->data.mp3); /* Deleting the MP3 closed the source if desired */ freesrc = SDL_FALSE; } else { smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer); music->error = 0; } } break; #elif defined(MP3_MAD_MUSIC) case MUS_MP3: music->type = MUS_MP3_MAD; music->data.mp3_mad = mad_openFileRW(src, &used_mixer, freesrc); if (music->data.mp3_mad) { music->error = 0; } else { Mix_SetError("Could not initialize MPEG stream."); } break; #endif #ifdef MID_MUSIC case MUS_MID: music->type = MUS_MID; #ifdef USE_NATIVE_MIDI if (native_midi_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.nativemidi = native_midi_loadsong_RW(src, freesrc); if (music->data.nativemidi) { music->error = 0; } else { Mix_SetError("%s", native_midi_error()); } break; } #endif #ifdef USE_FLUIDSYNTH_MIDI if (fluidsynth_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.fluidsynthmidi = fluidsynth_loadsong_RW(src, freesrc); if (music->data.fluidsynthmidi) { music->error = 0; } break; } #endif #ifdef USE_TIMIDITY_MIDI if (timidity_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.midi = Timidity_LoadSong_RW(src, freesrc); if (music->data.midi) { music->error = 0; } else { Mix_SetError("%s", Timidity_Error()); } } else { Mix_SetError("%s", Timidity_Error()); } #endif break; #endif #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC) case MUS_MOD: #ifdef MODPLUG_MUSIC if (music->error) { SDL_RWseek(src, start, RW_SEEK_SET); music->type = MUS_MODPLUG; music->data.modplug = modplug_new_RW(src, freesrc); if (music->data.modplug) { music->error = 0; } } #endif #ifdef MOD_MUSIC if (music->error) { SDL_RWseek(src, start, RW_SEEK_SET); music->type = MUS_MOD; music->data.module = MOD_new_RW(src, freesrc); if (music->data.module) { music->error = 0; } } #endif break; #endif default: Mix_SetError("Unrecognized music format"); break; } /* switch (want) */ if (music->error) { SDL_free(music); if (freesrc) { SDL_RWclose(src); } else { SDL_RWseek(src, start, RW_SEEK_SET); } music = NULL; } return music; }
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, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); } else { SDL_InitFormat(&format, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x00FF0000, 0x0000FF00, 0x000000FF, #else 0x000000FF, 0x0000FF00, 0x00FF0000, #endif 0); } 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); }
static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin) { return SDL_RWseek((SDL_RWops*)fd, offset, origin); }
//------------------------------------------------------------------------------------ // Открытие (подключение) VFS //------------------------------------------------------------------------------------ int vw_OpenVFS(const char *Name, unsigned int BuildNumber) { unsigned int vfsBuildNumber = 0; int POS = 0; // указатель позиции в буфере. BYTE *buff = 0; int HeaderOffsetVFS; int HeaderLengthVFS; // Начальная подготовка структуры списка... eVFS *TempVFS = 0; TempVFS = new eVFS; if (TempVFS == 0) return -1; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // открываем файл VFS //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TempVFS->File = 0; TempVFS->File = SDL_RWFromFile(Name, "rb"); if (TempVFS->File == NULL) { fprintf(stderr, "Can't find VFS file %s\n", Name); return -1; // ERROR } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // выделяем память для имени //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TempVFS->FileName = 0; TempVFS->FileName = new char[strlen(Name)+1]; if (TempVFS->FileName == 0) return -1; strcpy(TempVFS->FileName, Name); // первый в списке... if (EndVFS == 0) { TempVFS->Prev = 0; TempVFS->Next = 0; StartVFS = TempVFS; EndVFS = TempVFS; } else // продолжаем заполнение... { TempVFS->Prev = EndVFS; TempVFS->Next = 0; EndVFS->Next = TempVFS; EndVFS = TempVFS; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Проверяем сигнатуру "VFS_" - 4 байт //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ char Sign[5]; Sign[4] = 0; if(SDL_RWread(TempVFS->File, &Sign, 4, 1) == -1) { // если файл меньше, значит ошибка fprintf(stderr, "VFS file size error %s\n", Name); goto vw_OpenVFS_Error; } if (strncmp(Sign, "VFS_", 4) != 0) { // нет сигнатуры fprintf(stderr, "VFS file header error %s\n", Name); goto vw_OpenVFS_Error; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Bерсия - 4 байт //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ char Version[5]; Version[4] = 0; if(SDL_RWread(TempVFS->File, &Version, 4, 1) == -1) { fprintf(stderr, "VFS file corrupted: %s\n", Name); goto vw_OpenVFS_Error; } if (strncmp(Version, "v1.5", 4) != 0) { fprintf(stderr, "VFS file has wrong version, version %s not supported: %s\n", Version, Name); goto vw_OpenVFS_Error; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Билд - 4 байт (если предали ноль - проверять билды не нужно) //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(SDL_RWread(TempVFS->File, &vfsBuildNumber, 4, 1) == -1) { fprintf(stderr, "VFS file corrupted: %s\n", Name); goto vw_OpenVFS_Error; } // если передали ноль - проверка не нужна if (BuildNumber != 0) { if (vfsBuildNumber == 0) { printf("VFS file build number was not set (0).\n"); } else { if (BuildNumber != vfsBuildNumber) { fprintf(stderr, "VFS file has wrong build number (%i), you need VFS with build number %i\n", vfsBuildNumber, BuildNumber); goto vw_OpenVFS_Error; } } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // читаем смещение таблицы данных VFS - 4 байт //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDL_RWread(TempVFS->File, &HeaderOffsetVFS, sizeof(HeaderOffsetVFS), 1); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // читаем длину таблицы данных VFS //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDL_RWread(TempVFS->File, &HeaderLengthVFS, sizeof(HeaderLengthVFS), 1); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Читаем в буфер всю таблицу //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDL_RWseek(TempVFS->File, HeaderOffsetVFS, SEEK_SET); buff = new BYTE[HeaderLengthVFS]; if (buff == 0) return -1; SDL_RWread(TempVFS->File, buff, HeaderLengthVFS, 1); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Составляем (дополняем) список доступных файлов //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDL_RWseek(TempVFS->File, HeaderOffsetVFS, SEEK_SET); while (POS<HeaderLengthVFS) { // Начальная подготовка структуры списка... eVFS_Entry *Temp = 0; Temp = new eVFS_Entry; if (Temp == 0) return -1; // первый в списке... if (EndVFSArray == 0) { Temp->Prev = 0; Temp->Next = 0; StarVFSArray = Temp; EndVFSArray = Temp; } else // продолжаем заполнение... { Temp->Prev = EndVFSArray; Temp->Next = 0; EndVFSArray->Next = Temp; EndVFSArray = Temp; } Temp->Parent = TempVFS; SDL_RWseek(TempVFS->File, 1, SEEK_CUR); Temp->ArhKeyLen = buff[POS]; Temp->ArhKey = new char[Temp->ArhKeyLen+1]; if (Temp->ArhKey == 0) return -1; Temp->ArhKey[Temp->ArhKeyLen] = 0;// последний символ всегда ноль - конец строки SDL_RWread(TempVFS->File, Temp->ArhKey, Temp->ArhKeyLen, 1); SDL_RWseek(TempVFS->File, 2, SEEK_CUR); Temp->NameLen = buff[POS+1+Temp->ArhKeyLen+1]*0x100+buff[POS+Temp->ArhKeyLen+1]; Temp->Name = new char[Temp->NameLen+1]; if (Temp->Name == 0) return -1; Temp->Name[Temp->NameLen] = 0;// последний символ всегда ноль - конец строки SDL_RWread(TempVFS->File, Temp->Name, Temp->NameLen, 1); Temp->Link = false; SDL_RWread(TempVFS->File, &(Temp->Offset), sizeof(Temp->Offset), 1); SDL_RWread(TempVFS->File, &(Temp->Length), sizeof(Temp->Length), 1); SDL_RWread(TempVFS->File, &(Temp->RealLength), sizeof(Temp->RealLength), 1); POS = POS + 1 + Temp->ArhKeyLen + 2 + Temp->NameLen + 4 + 4 + 4; } // Освобождаем память... if (buff != 0){delete [] buff; buff = 0;} // выходим, все хорошо printf("VFS file was opened %s\n", Name); return 0; // была ошибка vw_OpenVFS_Error: SDL_RWclose(TempVFS->File); if (TempVFS->FileName != 0){delete [] TempVFS->FileName; TempVFS->FileName = 0;} return -1; }