KrSpriteResource::KrSpriteResource( U32 size, SDL_RWops* data ) { gedString name; ReadString( data, &name ); U32 id = SDL_ReadLE32( data ); SetNameAndId( name, id ); #ifdef DEBUG GLOUTPUT( "Sprite or Font resource '%s' id=%d\n", name.c_str(), id ); #endif U32 nAction = SDL_ReadLE32( data ); actionArr.SetCount( nAction ); actionMap = new GlMap< gedString, KrAction*, GlStringHash >( nAction ); actionIdMap = new GlMap< U32, KrAction*, GlNumberHash< U32 > >( nAction ); for ( U32 i=0; i<nAction; i++ ) { actionArr[ i ] = new KrAction( data ); actionMap->Add( actionArr[i]->Name(), actionArr[i] ); actionIdMap->Add( actionArr[i]->Id(), actionArr[i] ); } }
U8 *Compression::Decompression(const char *from, int &lenght) { U8 *out = NULL; int lenghtComp; SDL_RWops *src = ged_SDL_RWFromFile(from, "rb"); if(!src) return NULL; lenght = SDL_ReadLE32( src ); lenghtComp = SDL_ReadLE32( src ); out = new U8[lenght]; if(lenghtComp < lenght) { U8 *in = new U8[lenghtComp]; SDL_RWread(src, in, lenghtComp, 1); Decompression(in, lenghtComp, out, lenght, false); delete [] in; } else { SDL_RWread(src, out, lenght, 1); lenght; } SDL_RWclose(src); return out; }
static bool replay_read_meta(Replay *rpy, SDL_RWops *file, int64_t filesize, const char *source) { uint16_t version = rpy->version & ~REPLAY_VERSION_COMPRESSION_BIT; replay_read_string(file, &rpy->playername, version); PRINTPROP(rpy->playername, s); if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { CHECKPROP(rpy->flags = SDL_ReadLE32(file), u); } CHECKPROP(rpy->numstages = SDL_ReadLE16(file), u); if(!rpy->numstages) { log_warn("%s: No stages in replay", source); return false; } rpy->stages = malloc(sizeof(ReplayStage) * rpy->numstages); memset(rpy->stages, 0, sizeof(ReplayStage) * rpy->numstages); for(int i = 0; i < rpy->numstages; ++i) { ReplayStage *stg = rpy->stages + i; if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { CHECKPROP(stg->flags = SDL_ReadLE32(file), u); } CHECKPROP(stg->stage = SDL_ReadLE16(file), u); CHECKPROP(stg->seed = SDL_ReadLE32(file), u); CHECKPROP(stg->diff = SDL_ReadU8(file), u); CHECKPROP(stg->plr_points = SDL_ReadLE32(file), u); if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { CHECKPROP(stg->plr_continues_used = SDL_ReadU8(file), u); } CHECKPROP(stg->plr_char = SDL_ReadU8(file), u); CHECKPROP(stg->plr_shot = SDL_ReadU8(file), u); CHECKPROP(stg->plr_pos_x = SDL_ReadLE16(file), u); CHECKPROP(stg->plr_pos_y = SDL_ReadLE16(file), u); CHECKPROP(stg->plr_focus = SDL_ReadU8(file), u); CHECKPROP(stg->plr_power = SDL_ReadLE16(file), u); CHECKPROP(stg->plr_lives = SDL_ReadU8(file), u); CHECKPROP(stg->plr_life_fragments = SDL_ReadU8(file), u); CHECKPROP(stg->plr_bombs = SDL_ReadU8(file), u); CHECKPROP(stg->plr_bomb_fragments = SDL_ReadU8(file), u); CHECKPROP(stg->plr_inputflags = SDL_ReadU8(file), u); CHECKPROP(stg->numevents = SDL_ReadLE16(file), u); if(replay_calc_stageinfo_checksum(stg, version) + SDL_ReadLE32(file)) { log_warn("%s: Stageinfo is corrupt", source); return false; } } return true; }
tqt::tqt(const char* filename) // Constructor. Open the file and read the table of contents. Keep // the stream open in order to load textures on demand. { m_source = SDL_RWFromFile(filename, "rb"); if (m_source == NULL) { throw "tqt::tqt() can't open file."; } // Read header. tqt_header_info info = read_tqt_header_info(m_source); if (info.m_version != TQT_VERSION) { m_source = NULL; throw "tqt::tqt() incorrect file version."; return; // Hm. } m_depth = info.m_tree_depth; m_tile_size = info.m_tile_size; // Read table of contents. Each entry is the offset of the // index'ed tile's JPEG data, relative to the start of the file. m_toc.resize(node_count(m_depth)); for (int i = 0; i < node_count(m_depth); i++) { m_toc[i] = SDL_ReadLE32(m_source); } }
static int ReadChunk(SDL_RWops *src, Chunk *chunk) { chunk->magic = SDL_ReadLE32(src); chunk->length = SDL_ReadLE32(src); chunk->data = (Uint8 *)malloc(chunk->length); if ( chunk->data == NULL ) { SDL_Error(SDL_ENOMEM); return(-1); } if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) { SDL_Error(SDL_EFREAD); free(chunk->data); return(-1); } return(chunk->length); }
//-------------------------------------------------------------------------------------------- float read_float_RW( SDL_RWops * rw ) { union { float f; Uint32 i; } convert; convert.i = SDL_ReadLE32( rw ); return convert.f; }
static bool replay_read_header(Replay *rpy, SDL_RWops *file, int64_t filesize, size_t *ofs, const char *source) { uint8_t header[sizeof(replay_magic_header)]; (*ofs) += sizeof(header); SDL_RWread(file, header, sizeof(header), 1); if(memcmp(header, replay_magic_header, sizeof(header))) { log_warn("%s: Incorrect header", source); return false; } CHECKPROP(rpy->version = SDL_ReadLE16(file), u); (*ofs) += 2; uint16_t base_version = (rpy->version & ~REPLAY_VERSION_COMPRESSION_BIT); bool compression = (rpy->version & REPLAY_VERSION_COMPRESSION_BIT); bool gamev_assumed = false; switch(base_version) { case REPLAY_STRUCT_VERSION_TS101000: { // legacy format with no versioning, assume v1.1 TAISEI_VERSION_SET(&rpy->game_version, 1, 1, 0, 0); gamev_assumed = true; break; } case REPLAY_STRUCT_VERSION_TS102000_REV0: case REPLAY_STRUCT_VERSION_TS102000_REV1: { if(taisei_version_read(file, &rpy->game_version) != TAISEI_VERSION_SIZE) { log_warn("%s: Failed to read game version", source); return false; } (*ofs) += TAISEI_VERSION_SIZE; break; } default: { log_warn("%s: Unknown struct version %u", source, base_version); return false; } } char *gamev = taisei_version_tostring(&rpy->game_version); log_info("Struct version %u (%scompressed), game version %s%s", base_version, compression ? "" : "un", gamev, gamev_assumed ? " (assumed)" : ""); free(gamev); if(compression) { CHECKPROP(rpy->fileoffset = SDL_ReadLE32(file), u); (*ofs) += 4; } return true; }
//XXX: gzip stores uncompressed stream size in last 4 bytes of file // if stream is larger then 4 Gb we are screwed static size_t getFileSize(const char* const filename) { auto source = SDL_RWops(); auto file = setupRWFromFile(&source, filename, "rb"); SDL_RWseek(file, -4, SEEK_END); const size_t size = SDL_ReadLE32(file); SDL_RWclose(file); return size; }
static tqt_header_info read_tqt_header_info(SDL_RWops* in) // Read .tqt header file info from the given stream, and return a // struct containing the info. If the file doesn't look like .tqt, // then set m_version in the return value to 0. { tqt_header_info info; int tag = SDL_ReadLE32(in); if (tag != 0x00747174 /* "tqt\0" */) { // Wrong header tag. info.m_version = 0; // signal invalid header. return info; } info.m_version = SDL_ReadLE32(in); info.m_tree_depth = SDL_ReadLE32(in); info.m_tile_size = SDL_ReadLE32(in); return info; }
Uint32 Source_SampleStream::FindChunk(SDL_RWops* rw, Uint32 wanted_id) { Uint32 subchunk_id = SDL_ReadLE32(rw); Uint32 subchunk_size = SDL_ReadLE32(rw); if (subchunk_id == wanted_id) { return subchunk_size; } const Uint32 FACT = 0x74636166; const Uint32 LIST = 0x5453494c; const Uint32 BEXT = 0x74786562; const Uint32 JUNK = 0x4B4E554A; while (subchunk_id == FACT || subchunk_id == LIST || subchunk_id == BEXT || subchunk_id == JUNK) { SDL_RWseek(rw, subchunk_size, RW_SEEK_CUR); subchunk_id = SDL_ReadLE32(rw); subchunk_size = SDL_ReadLE32(rw); if (subchunk_id == wanted_id) { return subchunk_size; } } return 0; }
//-------------------------------------------------------------------------------------------- Sint32 * load_SDL_glcmd_RW( SDL_RWops * rw, Sint32 * pdata, size_t size ) { // BB> this reads the raw command data. It will need to be scanned, switched to the // proper endian type, and decoded to be used. if ( NULL == pdata ) return pdata; memset( pdata, 0, size * sizeof( Sint32 ) ); if ( NULL == rw ) return pdata; for ( size_t i = 0; i < size; i++ ) { pdata[i] = SDL_ReadLE32( rw ); } return pdata; }
int init_gaia(void) { struct SDL_Surface *Z; struct SDL_RWops *F; Sint32 w; int i, x=0; if( (F = SDL_RWFromFile("data/hblk01.dat","r")) == NULL) abend(0); for(i=0; i < 256*6; i++) { w = SDL_ReadLE32(F); w = (w < 6144)? 0: (w - 6144) / 320; subtile_table[i] = w; x = (w > x)? w : x; } printf("Gaia tile module:\n + %d unique subtiles.\n", x); x++; if(!(Z = CreateZSurface(get_pal("data/hpal01.dat"), 32,16*x)) ) SDL_RWclose(F), abend(0); load_subtiles(F, Z->pixels, x); if(1) subtiles = Z; else { if( (subtiles = SDL_CreateRGBSurface(SDL_HWSURFACE, 32,16*x,32, RR,GG,BB,AA)) ) SDL_BlitSurface(Z, NULL, subtiles, NULL); SDL_FreeSurface(Z); } SDL_RWclose(F); lua_pushnumber(L, SCALE); lua_setfield(L, LUA_GLOBALSINDEX, "scale"); lua_register(L, "s2m", s2m); lua_register(L, "m2s", m2s); REG_CLASS(L, map); return subtiles != NULL; }
static bool replay_read_events(Replay *rpy, SDL_RWops *file, int64_t filesize, const char *source) { for(int i = 0; i < rpy->numstages; ++i) { ReplayStage *stg = rpy->stages + i; if(!stg->numevents) { log_warn("%s: No events in stage", source); return false; } stg->events = malloc(sizeof(ReplayEvent) * stg->numevents); memset(stg->events, 0, sizeof(ReplayEvent) * stg->numevents); for(int j = 0; j < stg->numevents; ++j) { ReplayEvent *evt = stg->events + j; CHECKPROP(evt->frame = SDL_ReadLE32(file), u); CHECKPROP(evt->type = SDL_ReadU8(file), u); CHECKPROP(evt->value = SDL_ReadLE16(file), u); } } return true; }
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) { SDL_bool was_error; Sint64 fp_offset = 0; int bmpPitch; int i, pad; SDL_Surface *surface; Uint32 Rmask = 0; Uint32 Gmask = 0; Uint32 Bmask = 0; Uint32 Amask = 0; SDL_Palette *palette; Uint8 *bits; Uint8 *top, *end; SDL_bool topDown; int ExpandBMP; SDL_bool haveRGBMasks = SDL_FALSE; SDL_bool haveAlphaMask = SDL_FALSE; SDL_bool correctAlpha = SDL_FALSE; /* The Win32 BMP file header (14 bytes) */ char magic[2]; /* Uint32 bfSize = 0; */ /* Uint16 bfReserved1 = 0; */ /* Uint16 bfReserved2 = 0; */ Uint32 bfOffBits = 0; /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ Uint32 biSize = 0; Sint32 biWidth = 0; Sint32 biHeight = 0; /* Uint16 biPlanes = 0; */ Uint16 biBitCount = 0; Uint32 biCompression = 0; /* Uint32 biSizeImage = 0; */ /* Sint32 biXPelsPerMeter = 0; */ /* Sint32 biYPelsPerMeter = 0; */ Uint32 biClrUsed = 0; /* Uint32 biClrImportant = 0; */ (void) haveRGBMasks; (void) haveAlphaMask; /* 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) { /* really old BITMAPCOREHEADER */ biWidth = (Uint32) SDL_ReadLE16(src); biHeight = (Uint32) SDL_ReadLE16(src); /* biPlanes = */ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = BI_RGB; } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */ Uint32 headerSize; 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); /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */ if (biSize == 64) { /* ignore these extra fields. */ if (biCompression == BI_BITFIELDS) { /* this value is actually huffman compression in this variant. */ SDL_SetError("Compressed BMP files not supported"); was_error = SDL_TRUE; goto done; } } else { /* This is complicated. If compression is BI_BITFIELDS, then we have 3 DWORDS that specify the RGB masks. This is either stored here in an BITMAPV2INFOHEADER (which only differs in that it adds these RGB masks) and biSize >= 52, or we've got these masks stored in the exact same place, but strictly speaking, this is the bmiColors field in BITMAPINFO immediately following the legacy v1 info header, just past biSize. */ if (biCompression == BI_BITFIELDS) { haveRGBMasks = SDL_TRUE; Rmask = SDL_ReadLE32(src); Gmask = SDL_ReadLE32(src); Bmask = SDL_ReadLE32(src); /* ...v3 adds an alpha mask. */ if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ haveAlphaMask = SDL_TRUE; Amask = SDL_ReadLE32(src); } } else { /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */ if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */ /*Rmask = */ SDL_ReadLE32(src); /*Gmask = */ SDL_ReadLE32(src); /*Bmask = */ SDL_ReadLE32(src); } if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ /*Amask = */ SDL_ReadLE32(src); } } /* Insert other fields here; Wikipedia and MSDN say we're up to v5 of this header, but we ignore those for now (they add gamma, color spaces, etc). Ignoring the weird OS/2 2.x format, we currently parse up to v3 correctly (hopefully!). */ } /* skip any header bytes we didn't handle... */ headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14)); if (biSize > headerSize) { SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR); } } 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 */ switch (biCompression) { case BI_RGB: /* If there are no masks, use the defaults */ SDL_assert(!haveRGBMasks); SDL_assert(!haveAlphaMask); /* 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: /* We don't know if this has alpha channel or not */ correctAlpha = SDL_TRUE; Amask = 0xFF000000; Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; break; default: break; } break; case BI_BITFIELDS: break; /* we handled this in the info header. */ 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) { SDL_assert(biBitCount <= 8); if (biClrUsed == 0) { biClrUsed = 1 << biBitCount; } if ((int) biClrUsed > palette->ncolors) { SDL_Color *colors; int ncolors = biClrUsed; colors = (SDL_Color *) SDL_realloc(palette->colors, ncolors * sizeof(*palette->colors)); if (!colors) { SDL_OutOfMemory(); was_error = SDL_TRUE; goto done; } palette->ncolors = ncolors; palette->colors = colors; } 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].a = 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].a, 1, 1); /* According to Microsoft documentation, the fourth element is reserved and must be zero, so we shouldn't treat it as alpha. */ palette->colors[i].a = SDL_ALPHA_OPAQUE; } } } /* 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; } } if (correctAlpha) { CorrectAlphaChannel(surface); } done: if (was_error) { if (src) { SDL_RWseek(src, fp_offset, RW_SEEK_SET); } SDL_FreeSurface(surface); surface = NULL; } if (freesrc && src) { SDL_RWclose(src); } return (surface); }
//-------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------- SDL_md2_header_t * load_SDL_md2_header_RW( SDL_RWops * rw, SDL_md2_header_t * pdata ) { if ( NULL == pdata ) return pdata; memset( pdata, 0, sizeof( SDL_md2_header_t ) ); if ( NULL == rw ) return pdata; pdata->ident = SDL_ReadLE32( rw ); pdata->version = SDL_ReadLE32( rw ); pdata->skinwidth = SDL_ReadLE32( rw ); pdata->skinheight = SDL_ReadLE32( rw ); pdata->framesize = SDL_ReadLE32( rw ); pdata->num_skins = SDL_ReadLE32( rw ); pdata->num_vertices = SDL_ReadLE32( rw ); pdata->num_st = SDL_ReadLE32( rw ); pdata->num_tris = SDL_ReadLE32( rw ); pdata->size_glcmds = SDL_ReadLE32( rw ); pdata->num_frames = SDL_ReadLE32( rw ); pdata->offset_skins = SDL_ReadLE32( rw ); pdata->offset_st = SDL_ReadLE32( rw ); pdata->offset_tris = SDL_ReadLE32( rw ); pdata->offset_frames = SDL_ReadLE32( rw ); pdata->offset_glcmds = SDL_ReadLE32( rw ); pdata->offset_end = SDL_ReadLE32( rw ); pdata->num_glcmds = -1; return pdata; }
/** * @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 %i", 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: %llu, got: %llu", 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: %llu, got: %llu", 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; }
/* static */ bt_array* bt_array::create(const char* filename) // Makes a bt_array accessor for the specified .bt data file. Returns // NULL if the file is not a valid .bt file, or if there are other // errors. { assert(filename); SDL_RWops* in = SDL_RWFromFile(filename, "rb"); if (in == 0) { // Can't open the file. // warning ... printf("can't open file %s\n", filename); return NULL; } // // Read .BT header. // // Create a bt_array instance, and load its members. bt_array* bt = new bt_array(); // File-type marker. char buf[11]; SDL_RWread(in, buf, 1, 10); buf[10] = 0; if (strcmp(buf, "binterr1.1") == 0 || strcmp(buf, "binterr1.2") == 0) { bt->m_file_ver = BT11; } else if (strcmp(buf, "binterr1.3") == 0) { bt->m_file_ver = BT13; } else { // Bad input file format. printf("input file %s is not .BT version 1.1, 1.2 or 1.3 format\n", filename); SDL_RWclose(in); delete bt; return NULL; } bt->m_width = SDL_ReadLE32(in); bt->m_height = SDL_ReadLE32(in); if (bt->m_width <= 0 || bt->m_height <= 0) { // invalid data size. printf("invalid data size: width = %d, height = %d\n", bt->m_width, bt->m_height); delete bt; SDL_RWclose(in); return NULL; } int sample_size = SDL_ReadLE16(in); bt->m_float_data = SDL_ReadLE16(in) == 1 ? true : false; if (bt->m_float_data && sample_size != 4) { // can't deal with floats that aren't 4 bytes. printf("invalid data format: float, but size = %d\n", sample_size); delete bt; SDL_RWclose(in); return NULL; } if (bt->m_float_data == false && sample_size != 2) { // can't deal with ints that aren't 2 bytes. printf("invalid data format: int, but size = %d\n", sample_size); delete bt; SDL_RWclose(in); return NULL; } bt->m_sizeof_element = bt->m_float_data ? 4 : 2; if (bt->m_file_ver == BT11) { bt->m_utm_flag = SDL_ReadLE16(in) ? true : false; } else { bt->m_horz_units = SDL_ReadLE16(in); } bt->m_utm_zone = SDL_ReadLE16(in); bt->m_datum = SDL_ReadLE16(in); bt->m_left = ReadDouble64(in); bt->m_right = ReadDouble64(in); bt->m_bottom = ReadDouble64(in); bt->m_top = ReadDouble64(in); if (bt->m_file_ver == BT13) { SDL_ReadLE16(in); // Skip 2-byte External projection flag union { float f; Uint32 l; } u; u.l = SDL_ReadLE32(in); bt->m_vertical_scale = (u.f > 0.f) ? u.f : 1.f; } else { bt->m_vertical_scale = 1.f; } // Close the file. SDL_RWclose(in); printf("width = %d, height = %d, sample_size = %d, left = %lf, right = %lf, bottom = %lf, top = %lf\n", bt->m_width, bt->m_height, sample_size, bt->m_left, bt->m_right, bt->m_bottom, bt->m_top); printf("vertical scale = %lf\n", bt->m_vertical_scale); // Reopen the data using memory-mapping. bt->m_data_size = sample_size * bt->m_width * bt->m_height; bt->m_data_size += BT_HEADER_SIZE; bt->m_data = mmap_util::map(bt->m_data_size, false, filename); if (bt->m_data == 0) { // Failed to open a memory-mapped view to the data. printf("mmap_util::map() failed on %s, size = %d\n", filename, bt->m_data_size); delete bt; return NULL; } // Initialize the (empty) cache. if (bt->m_width * 4096 < TOTAL_CACHE_BYTES) { // No point in caching -- the dataset isn't big enough // to stress mmap. bt->m_cache_height = 0; } else { // Figure out how big our cache lines should be. bt->m_cache_height = TOTAL_CACHE_BYTES / bt->m_width / bt->m_sizeof_element; } if (bt->m_cache_height) { bt->m_cache.resize(bt->m_width); } // Niello: not sure how this will work with the cache enabled bt->m_min_elev = bt->m_max_elev = bt->get_sample(0, 0); for (int w = 0; w < bt->m_width; w++) { for (int h = 0; h < bt->m_height; h++) { float elev = bt->get_sample(w, h); if (elev < bt->m_min_elev) bt->m_min_elev = elev; else if (elev > bt->m_max_elev) bt->m_max_elev = elev; } } return bt; }
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); }
static int lua_Mix_Load(State & state){ Stack * stack = state.stack; if (stack->is<LUA_TSTRING>(1)){ AudioSpec * interfaceAS = state.getInterface<AudioSpec>("LuaSDL_AudioSpec"); SDL_AudioSpec * inputSpec = interfaceAS->get(2); if (inputSpec){ const std::string filename = stack->toLString(1); SDL_RWops * src = SDL_RWFromFile(filename.c_str(), "rb"); if (!src){ state.error("Couldn't open audio file: %s\n", filename.c_str()); } Uint32 magic; SDL_AudioSpec wavespec, *audiospec = nullptr; Uint8 *abuf = nullptr; Uint32 alen; /* note: send a copy of the mixer spec */ wavespec = *inputSpec; /* 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: audiospec = SDL_LoadWAV_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; case FORM: audiospec = Mix_LoadAIFF_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; case OGGS: audiospec = Mix_LoadOGG_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; case FLAC: audiospec = Mix_LoadFLAC_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; case CREA: audiospec = Mix_LoadVOC_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; default: if (detect_mp3((Uint8*)&magic)) { audiospec = Mix_LoadMP3_RW(src, 0, &wavespec, (Uint8 **)&abuf, &alen); break; } break; } SDL_RWclose(src); if (audiospec) { stack->pushLString(std::string(reinterpret_cast<char*>(abuf), alen)); interfaceAS->push(audiospec, true); return 2; } else{ state.error("Unreckonized audio file\n"); } } } return 0; }
SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { int was_error; Chunk chunk; int lenread; int MS_ADPCM_encoded, IMA_ADPCM_encoded; int samplesize; /* WAV magic header */ Uint32 RIFFchunk; Uint32 wavelen; Uint32 WAVEmagic; /* FMT chunk */ WaveFMT *format = NULL; /* Make sure we are passed a valid data source */ was_error = 0; if ( src == NULL ) { was_error = 1; goto done; } /* Check the magic header */ RIFFchunk = SDL_ReadLE32(src); wavelen = SDL_ReadLE32(src); if ( wavelen == WAVE ) { /* The RIFFchunk has already been read */ WAVEmagic = wavelen; wavelen = RIFFchunk; RIFFchunk = RIFF; } else { WAVEmagic = SDL_ReadLE32(src); } if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) { SDL_SetError("Unrecognized file type (not WAVE)"); was_error = 1; goto done; } /* Read the audio data format chunk */ chunk.data = NULL; do { if ( chunk.data != NULL ) { free(chunk.data); } lenread = ReadChunk(src, &chunk); if ( lenread < 0 ) { was_error = 1; goto done; } } while ( (chunk.magic == FACT) || (chunk.magic == LIST) ); /* Decode the audio data format */ format = (WaveFMT *)chunk.data; if ( chunk.magic != FMT ) { SDL_SetError("Complex WAVE files not supported"); was_error = 1; goto done; } MS_ADPCM_encoded = IMA_ADPCM_encoded = 0; switch (SDL_SwapLE16(format->encoding)) { case PCM_CODE: /* We can understand this */ break; case MS_ADPCM_CODE: /* Try to understand this */ if ( InitMS_ADPCM(format) < 0 ) { was_error = 1; goto done; } MS_ADPCM_encoded = 1; break; case IMA_ADPCM_CODE: /* Try to understand this */ if ( InitIMA_ADPCM(format) < 0 ) { was_error = 1; goto done; } IMA_ADPCM_encoded = 1; break; default: SDL_SetError("Unknown WAVE data format: 0x%.4x", SDL_SwapLE16(format->encoding)); was_error = 1; goto done; } memset(spec, 0, (sizeof *spec)); spec->freq = SDL_SwapLE32(format->frequency); switch (SDL_SwapLE16(format->bitspersample)) { case 4: if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) { spec->format = AUDIO_S16; } else { was_error = 1; } break; case 8: spec->format = AUDIO_U8; break; case 16: spec->format = AUDIO_S16; break; default: was_error = 1; break; } if ( was_error ) { SDL_SetError("Unknown %d-bit PCM data format", SDL_SwapLE16(format->bitspersample)); goto done; } spec->channels = (Uint8)SDL_SwapLE16(format->channels); spec->samples = 4096; /* Good default buffer size */ /* Read the audio data chunk */ *audio_buf = NULL; do { if ( *audio_buf != NULL ) { free(*audio_buf); } lenread = ReadChunk(src, &chunk); if ( lenread < 0 ) { was_error = 1; goto done; } *audio_len = lenread; *audio_buf = chunk.data; } while ( chunk.magic != DATA ); if ( MS_ADPCM_encoded ) { if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) { was_error = 1; goto done; } } if ( IMA_ADPCM_encoded ) { if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) { was_error = 1; goto done; } } /* Don't return a buffer that isn't a multiple of samplesize */ samplesize = ((spec->format & 0xFF)/8)*spec->channels; *audio_len &= ~(samplesize-1); done: if ( format != NULL ) { free(format); } if ( freesrc && src ) { SDL_RWclose(src); } if ( was_error ) { spec = NULL; } return(spec); }
/* 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 *)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: 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); } 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); }
bool Source_SampleStream::LoadWAV(SDL_RWops* rw) { Unload(); if (rw == NULL) { return false; } Source_SampleStream::rw = rw; Uint32 chunk_id = SDL_ReadLE32(rw); const Uint32 RIFF = 0x46464952; if (chunk_id != RIFF) { log_verbose("Not a WAV file"); return false; } Uint32 chunk_size = SDL_ReadLE32(rw); Uint32 chunk_format = SDL_ReadLE32(rw); const Uint32 WAVE = 0x45564157; if (chunk_format != WAVE) { log_verbose("Not in WAVE format"); return false; } const Uint32 FMT = 0x20746D66; Uint32 fmtchunk_size = FindChunk(rw, FMT); if (!fmtchunk_size) { log_verbose("Could not find FMT chunk"); return false; } Uint64 chunkstart = SDL_RWtell(rw); struct WaveFormat { Uint16 encoding; Uint16 channels; Uint32 frequency; Uint32 byterate; Uint16 blockalign; Uint16 bitspersample; } waveformat; SDL_RWread(rw, &waveformat, sizeof(waveformat), 1); SDL_RWseek(rw, chunkstart + fmtchunk_size, RW_SEEK_SET); const Uint16 pcmformat = 0x0001; if (waveformat.encoding != pcmformat) { log_verbose("Not in proper format"); return false; } format.freq = waveformat.frequency; switch (waveformat.bitspersample) { case 8: format.format = AUDIO_U8; break; case 16: format.format = AUDIO_S16LSB; break; default: log_verbose("Invalid bits per sample"); return false; break; } format.channels = waveformat.channels; const Uint32 DATA = 0x61746164; Uint32 datachunk_size = FindChunk(rw, DATA); if (!datachunk_size) { log_verbose("Could not find DATA chunk"); return false; } length = datachunk_size; databegin = SDL_RWtell(rw); return true; }