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;
}
Example #2
0
static int sdl_seek_func(void *datasource, ogg_int64_t offset, int whence)
{
    return SDL_RWseek((SDL_RWops*)datasource, (int)offset, whence);
}
Example #3
0
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;
}
Example #4
0
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
}
Example #6
0
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);
}
Example #7
0
/**
 * @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);
}
Example #8
0
static int ov_close_func_nofreesrc(void *datasource)
{
    return SDL_RWseek((SDL_RWops*)datasource, 0, RW_SEEK_SET);
}
Example #9
0
static int sdl_seek_func ( int pos, void *appdata )
{
	assert ( pos >= 0 );
	assert ( appdata );
	return SDL_RWseek ( ( SDL_RWops * ) appdata, pos, SEEK_SET );
}
Example #10
0
static int ovpack_seek( void *datasource, ogg_int64_t offset, int whence )
{
   SDL_RWops *rw = datasource;
   return SDL_RWseek( rw, offset, whence );
}
Example #11
0
static long ovpack_tell( void *datasource )
{
   SDL_RWops *rw = datasource;
   return SDL_RWseek( rw, 0, SEEK_CUR );
}
Example #12
0
/* 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);
}
Example #13
0
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);
}
Example #14
0
/* 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);
}
Example #15
0
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 */
Example #16
0
static int sdl_seek_to_end_func ( void *appdata )
{
	assert ( appdata );
	return SDL_RWseek ( ( SDL_RWops * ) appdata, 0, SEEK_END );
}
Example #17
0
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);
}
Example #18
0
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;

}
Example #19
0
/**
 * @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;
}
Example #20
0
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();
}
Example #21
0
    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;
    }
Example #22
0
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);
}
Example #23
0
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);
}
Example #24
0
 int seek(int offset, int whence)
 {
     return SDL_RWseek(rwops_, offset, whence);
 }
Example #25
0
/* 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);
}
Example #26
0
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
			{
Example #27
0
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;
}
Example #28
0
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);
}
Example #29
0
File: IMG_tif.c Project: Hoffa/nSDL
static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin)
{
	return SDL_RWseek((SDL_RWops*)fd, offset, origin);
}
Example #30
0
//------------------------------------------------------------------------------------
// Открытие (подключение) 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;
}