static FLAC__StreamDecoderLengthStatus flac_length_music_cb (
									const FLAC__StreamDecoder *decoder,
									FLAC__uint64 *stream_length,
									void *client_data)
{
	FLAC_music *data = (FLAC_music*)client_data;

	int pos = SDL_RWtell (data->rwops);
	int length = SDL_RWseek (data->rwops, 0, RW_SEEK_END);

	if (SDL_RWseek (data->rwops, pos, RW_SEEK_SET) != pos || length < 0) {
		/* there was an error attempting to return the stream to the original
		 * position, or the length was invalid. */
		return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
	}
	else {
		*stream_length = (FLAC__uint64)length;
		return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
	}
}
Example #2
0
/* See if an image is contained in a data source */
int IMG_isGIF(SDL_RWops *src)
{
    Sint64 start;
    int is_GIF;
    char magic[6];

    if ( !src )
        return 0;
    start = SDL_RWtell(src);
    is_GIF = 0;
    if ( SDL_RWread(src, magic, sizeof(magic), 1) ) {
        if ( (SDL_strncmp(magic, "GIF", 3) == 0) &&
             ((SDL_memcmp(magic + 3, "87a", 3) == 0) ||
              (SDL_memcmp(magic + 3, "89a", 3) == 0)) ) {
            is_GIF = 1;
        }
    }
    SDL_RWseek(src, start, RW_SEEK_SET);
    return(is_GIF);
}
Example #3
0
MREADER *_mm_new_rwops_reader(SDL_RWops * rw)
{
	int here;
	MRWOPSREADER* reader=(MRWOPSREADER*)_mm_malloc(sizeof(MRWOPSREADER));
	if (reader) {
		reader->core.Eof =&_mm_RWopsReader_Eof;
		reader->core.Read=&_mm_RWopsReader_Read;
		reader->core.Get =&_mm_RWopsReader_Get;
		reader->core.Seek=&_mm_RWopsReader_Seek;
		reader->core.Tell=&_mm_RWopsReader_Tell;
		reader->rw=rw;

		/* RWops does not explicitly support an eof check, so we shall find
		   the end manually - this requires seek support for the RWop */
		here = SDL_RWtell(rw);
		reader->end = SDL_RWseek(rw, 0, SEEK_END);
		SDL_RWseek(rw, here, SEEK_SET);   /* Move back */
	}
	return (MREADER*)reader;
}
static FLAC__bool flac_eof_music_cb(
								const FLAC__StreamDecoder *decoder,
								void *client_data )
{
	FLAC_music *data = (FLAC_music*)client_data;

	int pos = SDL_RWtell (data->rwops);
	int end = SDL_RWseek (data->rwops, 0, RW_SEEK_END);

	// was the original position equal to the end (a.k.a. the seek didn't move)?
	if (pos == end) {
		// must be EOF
		return true;
	}
	else {
		// not EOF, return to the original position
		SDL_RWseek (data->rwops, pos, RW_SEEK_SET);

		return false;
	}
}
Example #5
0
static int isLBM()
{
    SDL_RWops* src = 0;
    int start;
    int   is_LBM;
    Uint8 magic[4+4+4];

    start = SDL_RWtell(src);
    is_LBM = 0;
    if ( SDL_RWread( src, magic, sizeof(magic), 1 ) )
    {
        if ( !memcmp( magic, "FORM", 4 ) &&
            ( !memcmp( magic + 8, "PBM ", 4 ) ||
              !memcmp( magic + 8, "ILBM", 4 ) ) )
        {
            is_LBM = 1;
        }
    }
    SDL_RWseek(src, start, SEEK_SET);
    return( is_LBM );
}
Example #6
0
File: IMG_png.c Project: jjgod/SDL
/* See if an image is contained in a data source */
int IMG_isPNG(SDL_RWops *src)
{
	int start;
	int is_PNG;
	Uint8 magic[4];

	if ( !src )
		return 0;
	start = SDL_RWtell(src);
	is_PNG = 0;
	if ( SDL_RWread(src, magic, 1, sizeof(magic)) == sizeof(magic) ) {
                if ( magic[0] == 0x89 &&
                     magic[1] == 'P' &&
                     magic[2] == 'N' &&
                     magic[3] == 'G' ) {
			is_PNG = 1;
		}
	}
	SDL_RWseek(src, start, SEEK_SET);
	return(is_PNG);
}
Example #7
0
bool Serializer::writeScriptData() {
  int64_t fieldsPtr = SDL_RWtell(_rw);
  if (fieldsPtr < 0)
    return false;
  if (!SDL_WriteBE32(_rw, 0)) // 4 placeholder bytes for the actual number of fields
    return false;

  lua_getglobal(_L, "dgPersistence");
  int32_t numFields = writeTable("dgPersistence");
  if (numFields < 0)
    return false;

  if (SDL_RWseek(_rw, fieldsPtr, RW_SEEK_SET) < 0) // Restore file pointer to 4 placeholder bytes
    return false;
  if (!SDL_WriteBE32(_rw, numFields))
    return false;
  if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end
    return false;

  return true;
}
Example #8
0
int IMG_isLBM( SDL_RWops *src )
{
    Sint64 start;
    int   is_LBM;
    Uint8 magic[4+4+4];

    if ( !src )
        return 0;
    start = SDL_RWtell(src);
    is_LBM = 0;
    if ( SDL_RWread( src, magic, sizeof(magic), 1 ) )
    {
        if ( !SDL_memcmp( magic, "FORM", 4 ) &&
            ( !SDL_memcmp( magic + 8, "PBM ", 4 ) ||
              !SDL_memcmp( magic + 8, "ILBM", 4 ) ) )
        {
            is_LBM = 1;
        }
    }
    SDL_RWseek(src, start, RW_SEEK_SET);
    return( is_LBM );
}
Example #9
0
//------------------------------------------------------------------------------------
// запись данных в VFS
//------------------------------------------------------------------------------------
int vw_WriteIntoVFSfromFile(const char *SrcName, const char *DstName)
{
	if (SrcName == 0) return -1;
	if (DstName == 0) return -1;

	// читаем данные файла в буфер
	SDL_RWops *Ftmp = SDL_RWFromFile(SrcName, "rb");
	// Если файл не найден - выходим
	if (Ftmp == NULL)
    {
		fprintf(stderr, "Can't find file %s !!!\n", SrcName);
        return -1;
    }

	// получаем размер файла
	SDL_RWseek(Ftmp, 0, SEEK_END);
	int tmpLength = SDL_RWtell(Ftmp);
	SDL_RWseek(Ftmp, 0, SEEK_SET);

	// копируем все данные файла в массив
	BYTE *tmp = 0;
	tmp = new BYTE[tmpLength];
	SDL_RWread(Ftmp, tmp, tmpLength, 1);
	SDL_RWclose(Ftmp);

	// запись в VFS
	if (0 != vw_WriteIntoVFSfromMemory(DstName, tmp, tmpLength))
	{
		// какая-то ошибка, не можем записать в VFS
		delete [] tmp; tmp = 0;
		fprintf(stderr, "Can't write into VFS from memory %s !!!\n", DstName);
		return -1;
	}

	// Освобождаем память
	delete [] tmp; tmp = 0;

	return 0;
}
Example #10
0
/*--------------------------------------------------------------------------*/
int AG_isGIF( SDL_RWops* src )
{
	int isGIF = FALSE;

	if ( src )
	{
		int start = SDL_RWtell( src );
		char magic[6];

		if ( SDL_RWread(src,magic,sizeof(magic),1) )
		{
			if ( (strncmp(magic,"GIF",3) == 0) && ((memcmp(magic+3,"87a",3) == 0) || (memcmp(magic+3,"89a",3) == 0)) )
			{
				isGIF = TRUE;
			}
		}

		SDL_RWseek( src, start, SEEK_SET );
	}

	return isGIF;
}
Example #11
0
void Compression::DoCompression(const char *from, SDL_RWops *dst)
{
	int lenght, lenghtComp; 
	
	SDL_RWops *src = ged_SDL_RWFromFile(from, "rb");
	if(!src) return;
	
	SDL_RWseek( src, 0, SEEK_END );
	lenght = SDL_RWtell( src );
	SDL_RWseek( src, 0, SEEK_SET );
	
	U8 *in = new U8[lenght];
	U8 *out = new U8[2*lenght/*lenght + lenght / 8 + 256*/]; //Solved crash when export Alittlecash_player.ged
	
	SDL_RWread(src, in, lenght, 1);
	lenghtComp = DoCompression(in, lenght, out, 2*lenght/*lenght + lenght / 8 + 256*/);
	
	if(lenghtComp < lenght)
	{
		SDL_WriteLE32( dst, lenght );
		SDL_WriteLE32( dst, lenghtComp );
		SDL_RWwrite(dst, out, lenghtComp, 1);
	}
	else
	{
		//No compression
		SDL_WriteLE32( dst, lenght );
		SDL_WriteLE32( dst, lenght );
		SDL_RWwrite(dst, in, lenght, 1);
	}
	
	
	
	delete [] in;
	delete [] out;
	
	SDL_RWclose(src);	
}
Example #12
0
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw)
{
	NativeMidiSong	*song = NULL;
	char 		*extra;

	song = malloc(sizeof(NativeMidiSong));
	if (!song) {
		return NULL;
	};

	SDL_RWseek(rw, 0, SEEK_END);
	song->file_size = SDL_RWtell(rw);
	SDL_RWseek(rw, 0, SEEK_SET);

	song->filebuf = malloc(song->file_size);
	if (!song->filebuf) {
		free(song);
		return NULL;
	}

	SDL_RWread(rw, song->filebuf, song->file_size, 1);
	return song;
}
Example #13
0
File: IMG_pcx.c Project: jjgod/SDL
/* See if an image is contained in a data source */
int IMG_isPCX(SDL_RWops *src)
{
    int start;
    int is_PCX;
    const int ZSoft_Manufacturer = 10;
    const int PC_Paintbrush_Version = 5;
    const int PCX_RunLength_Encoding = 1;
    struct PCXheader pcxh;

    if ( !src )
        return 0;
    start = SDL_RWtell(src);
    is_PCX = 0;
    if ( SDL_RWread(src, &pcxh, sizeof(pcxh), 1) == 1 ) {
        if ( (pcxh.Manufacturer == ZSoft_Manufacturer) &&
                (pcxh.Version == PC_Paintbrush_Version) &&
                (pcxh.Encoding == PCX_RunLength_Encoding) ) {
            is_PCX = 1;
        }
    }
    SDL_RWseek(src, start, SEEK_SET);
    return(is_PCX);
}
Example #14
0
static MAD_WRAPPER* init( SDL_RWops *src )
{
    MAD_WRAPPER *mad = new MAD_WRAPPER;

    SDL_RWseek( src, 0, SEEK_END );
    mad->length = SDL_RWtell( src );
    SDL_RWseek( src, 0, SEEK_SET );

    mad->src = src;

	mad_stream_init( &mad->Stream );
	mad_frame_init( &mad->Frame );
	mad_synth_init( &mad->Synth );
    mad->volume = 64;
    
    mad->input_buf = new unsigned char[ INPUT_BUFFER_SIZE ];
    mad->output_buf = new unsigned char[ 1152*4*5 ]; /* 1152 because that's what mad has as a max; *4 because */
    mad->output_buf_index = 0;
    
    mad->is_playing = false;
    
    return mad;
}
Example #15
0
/* Load a XXX type image from an SDL datasource */
SDL_Surface *IMG_LoadXXX_RW(SDL_RWops *src)
{
    int start;
    const char *error = NULL;
    SDL_Surface *surface = NULL;

    if ( !src ) {
        /* The error message has been set in SDL_RWFromFile */
        return NULL;
    }
    start = SDL_RWtell(src);

    /* Load the image here */

    if ( error ) {
        SDL_RWseek(src, start, RW_SEEK_SET);
        if ( surface ) {
            SDL_FreeSurface(surface);
            surface = NULL;
        }
        IMG_SetError("%s", error);
    }
    return surface;
}
Example #16
0
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);
}
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) {
        SDL_bool save32bit = SDL_FALSE;
#ifdef SAVE_32BIT_BMP
        /* We can save alpha information in a 32-bit BMP */
        if (saveme->map->info.flags & SDL_COPY_COLORKEY ||
            saveme->format->Amask) {
            save32bit = SDL_TRUE;
        }
#endif /* SAVE_32BIT_BMP */

        if (saveme->format->palette && !save32bit) {
            if (saveme->format->BitsPerPixel == 8) {
                surface = saveme;
            } else {
                SDL_SetError("%d bpp BMP files not supported",
                             saveme->format->BitsPerPixel);
            }
        } else if ((saveme->format->BitsPerPixel == 24) &&
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
                   (saveme->format->Rmask == 0x00FF0000) &&
                   (saveme->format->Gmask == 0x0000FF00) &&
                   (saveme->format->Bmask == 0x000000FF)
#else
                   (saveme->format->Rmask == 0x000000FF) &&
                   (saveme->format->Gmask == 0x0000FF00) &&
                   (saveme->format->Bmask == 0x00FF0000)
#endif
            ) {
            surface = saveme;
        } else {
            SDL_PixelFormat format;

            /* If the surface has a colorkey or alpha channel we'll save a
               32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
            if (save32bit) {
                SDL_InitFormat(&format, 
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
                               SDL_PIXELFORMAT_ARGB8888
#else
                               SDL_PIXELFORMAT_BGRA8888
#endif
                               );
            } else {
                SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
            }
            surface = SDL_ConvertSurface(saveme, &format, 0);
            if (!surface) {
                SDL_SetError("Couldn't convert image to %d bpp",
                             format.BitsPerPixel);
            }
        }
    }

    if (surface && (SDL_LockSurface(surface) == 0)) {
        const int bw = surface->w * surface->format->BytesPerPixel;

        /* Set the BMP file header values */
        bfSize = 0;             /* We'll write this when we're done */
        bfReserved1 = 0;
        bfReserved2 = 0;
        bfOffBits = 0;          /* We'll write this when we're done */

        /* Write the BMP file header values */
        fp_offset = SDL_RWtell(dst);
        SDL_ClearError();
        SDL_RWwrite(dst, magic, 2, 1);
        SDL_WriteLE32(dst, bfSize);
        SDL_WriteLE16(dst, bfReserved1);
        SDL_WriteLE16(dst, bfReserved2);
        SDL_WriteLE32(dst, bfOffBits);

        /* Set the BMP info values */
        biSize = 40;
        biWidth = surface->w;
        biHeight = surface->h;
        biPlanes = 1;
        biBitCount = surface->format->BitsPerPixel;
        biCompression = BI_RGB;
        biSizeImage = surface->h * surface->pitch;
        biXPelsPerMeter = 0;
        biYPelsPerMeter = 0;
        if (surface->format->palette) {
            biClrUsed = surface->format->palette->ncolors;
        } else {
            biClrUsed = 0;
        }
        biClrImportant = 0;

        /* Write the BMP info values */
        SDL_WriteLE32(dst, biSize);
        SDL_WriteLE32(dst, biWidth);
        SDL_WriteLE32(dst, biHeight);
        SDL_WriteLE16(dst, biPlanes);
        SDL_WriteLE16(dst, biBitCount);
        SDL_WriteLE32(dst, biCompression);
        SDL_WriteLE32(dst, biSizeImage);
        SDL_WriteLE32(dst, biXPelsPerMeter);
        SDL_WriteLE32(dst, biYPelsPerMeter);
        SDL_WriteLE32(dst, biClrUsed);
        SDL_WriteLE32(dst, biClrImportant);

        /* Write the palette (in BGR color order) */
        if (surface->format->palette) {
            SDL_Color *colors;
            int ncolors;

            colors = surface->format->palette->colors;
            ncolors = surface->format->palette->ncolors;
            for (i = 0; i < ncolors; ++i) {
                SDL_RWwrite(dst, &colors[i].b, 1, 1);
                SDL_RWwrite(dst, &colors[i].g, 1, 1);
                SDL_RWwrite(dst, &colors[i].r, 1, 1);
                SDL_RWwrite(dst, &colors[i].unused, 1, 1);
            }
        }

        /* Write the bitmap offset */
        bfOffBits = SDL_RWtell(dst) - fp_offset;
        if (SDL_RWseek(dst, fp_offset + 10, RW_SEEK_SET) < 0) {
            SDL_Error(SDL_EFSEEK);
        }
        SDL_WriteLE32(dst, bfOffBits);
        if (SDL_RWseek(dst, fp_offset + bfOffBits, RW_SEEK_SET) < 0) {
            SDL_Error(SDL_EFSEEK);
        }

        /* Write the bitmap image upside down */
        bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch);
        pad = ((bw % 4) ? (4 - (bw % 4)) : 0);
        while (bits > (Uint8 *) surface->pixels) {
            bits -= surface->pitch;
            if (SDL_RWwrite(dst, bits, 1, bw) != bw) {
                SDL_Error(SDL_EFWRITE);
                break;
            }
            if (pad) {
                const Uint8 padbyte = 0;
                for (i = 0; i < pad; ++i) {
                    SDL_RWwrite(dst, &padbyte, 1, 1);
                }
            }
        }

        /* Write the BMP file size */
        bfSize = SDL_RWtell(dst) - fp_offset;
        if (SDL_RWseek(dst, fp_offset + 2, RW_SEEK_SET) < 0) {
            SDL_Error(SDL_EFSEEK);
        }
        SDL_WriteLE32(dst, bfSize);
        if (SDL_RWseek(dst, fp_offset + bfSize, RW_SEEK_SET) < 0) {
            SDL_Error(SDL_EFSEEK);
        }

        /* Close it up.. */
        SDL_UnlockSurface(surface);
        if (surface != saveme) {
            SDL_FreeSurface(surface);
        }
    }

    if (freedst && dst) {
        SDL_RWclose(dst);
    }
    return ((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1);
}
Example #18
0
size_t BaseFile::tell()
{
    SDL_RWops * rw = (SDL_RWops*)handle;
    return SDL_RWtell(rw);
}
Example #19
0
SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src )
{
	int start;
	SDL_Surface *Image;
	Uint8       id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk;
	Uint32      size, bytesloaded, nbcolors;
	Uint32      i, j, bytesperline, nbplanes, stencil, plane, h;
	Uint32      remainingbytes;
	Uint32      width;
	BMHD	      bmhd;
	char        *error;
	Uint8       flagHAM,flagEHB;

	Image   = NULL;
	error   = NULL;
	MiniBuf = NULL;

	if ( !src ) {
		/* The error message has been set in SDL_RWFromFile */
		return NULL;
	}
	start = SDL_RWtell(src);

	if ( !SDL_RWread( src, id, 4, 1 ) )
	{
		error="error reading IFF chunk";
		goto done;
	}

	/* Should be the size of the file minus 4+4 ( 'FORM'+size ) */
	if ( !SDL_RWread( src, &size, 4, 1 ) )
	{
		error="error reading IFF chunk size";
		goto done;
	}

	/* As size is not used here, no need to swap it */

	if ( memcmp( id, "FORM", 4 ) != 0 )
	{
		error="not a IFF file";
		goto done;
	}

	if ( !SDL_RWread( src, id, 4, 1 ) )
	{
		error="error reading IFF chunk";
		goto done;
	}

	pbm = 0;

	/* File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap */
	if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1;
	else if ( memcmp( id, "ILBM", 4 ) )
	{
		error="not a IFF picture";
		goto done;
	}

	nbcolors = 0;

	memset( &bmhd, 0, sizeof( BMHD ) );
	flagHAM = 0;
	flagEHB = 0;

	while ( memcmp( id, "BODY", 4 ) != 0 )
	{
		if ( !SDL_RWread( src, id, 4, 1 ) ) 
		{
			error="error reading IFF chunk";
			goto done;
		}

		if ( !SDL_RWread( src, &size, 4, 1 ) )
		{
			error="error reading IFF chunk size";
			goto done;
		}

		bytesloaded = 0;

		size = SDL_SwapBE32( size );

		if ( !memcmp( id, "BMHD", 4 ) ) /* Bitmap header */
		{
			if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) )
			{
				error="error reading BMHD chunk";
				goto done;
			}

			bytesloaded = sizeof( BMHD );

			bmhd.w 		= SDL_SwapBE16( bmhd.w );
			bmhd.h 		= SDL_SwapBE16( bmhd.h );
			bmhd.x 		= SDL_SwapBE16( bmhd.x );
			bmhd.y 		= SDL_SwapBE16( bmhd.y );
			bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor );
			bmhd.Lpage 	= SDL_SwapBE16( bmhd.Lpage );
			bmhd.Hpage 	= SDL_SwapBE16( bmhd.Hpage );
		}

		if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */
		{
			if ( !SDL_RWread( src, &colormap, size, 1 ) )
			{
				error="error reading CMAP chunk";
				goto done;
			}

			bytesloaded = size;
			nbcolors = size / 3;
		}

		if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode  */
		{
			Uint32 viewmodes;
			if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) )
			{
				error="error reading CAMG chunk";
				goto done;
			}

			bytesloaded = size;
			viewmodes = SDL_SwapBE32( viewmodes );
			if ( viewmodes & 0x0800 )
				flagHAM = 1;
			if ( viewmodes & 0x0080 )
				flagEHB = 1;
		}

		if ( memcmp( id, "BODY", 4 ) )
		{
			if ( size & 1 )	++size;  	/* padding ! */
			size -= bytesloaded;
			/* skip the remaining bytes of this chunk */
			if ( size )	SDL_RWseek( src, size, RW_SEEK_CUR );
		}
	}

	/* compute some usefull values, based on the bitmap header */

	width = ( bmhd.w + 15 ) & 0xFFFFFFF0;  /* Width in pixels modulo 16 */

	bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2;

	nbplanes = bmhd.planes;

	if ( pbm )                         /* File format : 'Packed Bitmap' */
	{
		bytesperline *= 8;
		nbplanes = 1;
	}

	stencil = (bmhd.mask & 1);   /* There is a mask ( 'stencil' ) */

	/* Allocate memory for a temporary buffer ( used for
           decompression/deinterleaving ) */

	MiniBuf = (void *)malloc( bytesperline * (nbplanes + stencil) );
	if ( MiniBuf == NULL )
	{
		error="no enough memory for temporary buffer";
		goto done;
	}

	if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL )
	   goto done;

	if ( bmhd.mask & 2 )               /* There is a transparent color */
		SDL_SetColorKey( Image, SDL_SRCCOLORKEY, bmhd.tcolor );

	/* Update palette informations */

	/* There is no palette in 24 bits ILBM file */
	if ( nbcolors>0 && flagHAM==0 )
	{
		/* FIXME: Should this include the stencil? See comment below */
		int nbrcolorsfinal = 1 << (nbplanes + stencil);
		ptr = &colormap[0];

		for ( i=0; i<nbcolors; i++ )
		{
			Image->format->palette->colors[i].r = *ptr++;
			Image->format->palette->colors[i].g = *ptr++;
			Image->format->palette->colors[i].b = *ptr++;
		}

		/* Amiga EHB mode (Extra-Half-Bright) */
		/* 6 bitplanes mode with a 32 colors palette */
		/* The 32 last colors are the same but divided by 2 */
		/* Some Amiga pictures save 64 colors with 32 last wrong colors, */
		/* they shouldn't !, and here we overwrite these 32 bad colors. */
		if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
		{
			nbcolors = 64;
			ptr = &colormap[0];
			for ( i=32; i<64; i++ )
			{
				Image->format->palette->colors[i].r = (*ptr++)/2;
				Image->format->palette->colors[i].g = (*ptr++)/2;
				Image->format->palette->colors[i].b = (*ptr++)/2;
			}
		}

		/* If nbcolors < 2^nbplanes, repeat the colormap */
		/* This happens when pictures have a stencil mask */
		if ( nbrcolorsfinal > (1<<bmhd.planes) ) {
			nbrcolorsfinal = (1<<bmhd.planes);
		}
		for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ )
		{
			Image->format->palette->colors[i].r = Image->format->palette->colors[i%nbcolors].r;
			Image->format->palette->colors[i].g = Image->format->palette->colors[i%nbcolors].g;
			Image->format->palette->colors[i].b = Image->format->palette->colors[i%nbcolors].b;
		}
		if ( !pbm )
			Image->format->palette->ncolors = nbrcolorsfinal;
	}

	/* Get the bitmap */

	for ( h=0; h < bmhd.h; h++ )
	{
		/* uncompress the datas of each planes */

		for ( plane=0; plane < (nbplanes+stencil); plane++ )
		{
			ptr = MiniBuf + ( plane * bytesperline );

			remainingbytes = bytesperline;

			if ( bmhd.tcomp == 1 )	    /* Datas are compressed */
			{
				do
				{
					if ( !SDL_RWread( src, &count, 1, 1 ) )
					{
						error="error reading BODY chunk";
						goto done;
					}

					if ( count & 0x80 )
					{
						count ^= 0xFF;
						count += 2; /* now it */

						if ( ( count > remainingbytes ) || !SDL_RWread( src, &color, 1, 1 ) )
						{
							error="error reading BODY chunk";
							goto done;
						}
						memset( ptr, color, count );
					}
					else
					{
						++count;

						if ( ( count > remainingbytes ) || !SDL_RWread( src, ptr, count, 1 ) )
						{
						   error="error reading BODY chunk";
							goto done;
						}
					}

					ptr += count;
					remainingbytes -= count;

				} while ( remainingbytes > 0 );
			}
			else
			{
				if ( !SDL_RWread( src, ptr, bytesperline, 1 ) )
				{
					error="error reading BODY chunk";
					goto done;
				}
			}
		}

		/* One line has been read, store it ! */

		ptr = Image->pixels;
		if ( nbplanes==24 || flagHAM==1 )
			ptr += h * width * 3;
		else
			ptr += h * width;

		if ( pbm )                 /* File format : 'Packed Bitmap' */
		{
		   memcpy( ptr, MiniBuf, width );
		}
		else		/* We have to un-interlace the bits ! */
		{
			if ( nbplanes!=24 && flagHAM==0 )
			{
				size = ( width + 7 ) / 8;

				for ( i=0; i < size; i++ )
				{
					memset( ptr, 0, 8 );

					for ( plane=0; plane < (nbplanes + stencil); plane++ )
					{
						color = *( MiniBuf + i + ( plane * bytesperline ) );
						msk = 0x80;

						for ( j=0; j<8; j++ )
						{
							if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j );
							else 	                    ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 );

							msk >>= 1;
						}
					}
					ptr += 8;
				}
			}
			else
			{
Example #20
0
/* read XPM from either array or RWops */
static SDL_Surface *load_xpm(char **xpm, SDL_RWops *src)
{
	int start = 0;
	SDL_Surface *image = NULL;
	int index;
	int x, y;
	int w, h, ncolors, cpp;
	int indexed;
	Uint8 *dst;
	struct color_hash *colors = NULL;
	SDL_Color *im_colors = NULL;
	char *keystrings = NULL, *nextkey;
	char *line;
	char ***xpmlines = NULL;
	int pixels_len;

	error = NULL;
	linebuf = NULL;
	buflen = 0;

	if ( src ) 
		start = SDL_RWtell(src);

	if(xpm)
		xpmlines = &xpm;

	line = get_next_line(xpmlines, src, 0);
	if(!line)
		goto done;
	/*
	 * The header string of an XPMv3 image has the format
	 *
	 * <width> <height> <ncolors> <cpp> [ <hotspot_x> <hotspot_y> ]
	 *
	 * where the hotspot coords are intended for mouse cursors.
	 * Right now we don't use the hotspots but it should be handled
	 * one day.
	 */
	if(sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4
	   || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) {
		error = "Invalid format description";
		goto done;
	}

	keystrings = malloc(ncolors * cpp);
	if(!keystrings) {
		error = "Out of memory";
		goto done;
	}
	nextkey = keystrings;

	/* Create the new surface */
	if(ncolors <= 256) {
		indexed = 1;
		image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8,
					     0, 0, 0, 0);
		im_colors = image->format->palette->colors;
		image->format->palette->ncolors = ncolors;
	} else {
		indexed = 0;
		image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32,
					     0xff0000, 0x00ff00, 0x0000ff, 0);
	}
	if(!image) {
		/* Hmm, some SDL error (out of memory?) */
		goto done;
	}

	/* Read the colors */
	colors = create_colorhash(ncolors);
	if (!colors) {
		error = "Out of memory";
		goto done;
	}
	for(index = 0; index < ncolors; ++index ) {
		char *p;
		line = get_next_line(xpmlines, src, 0);
		if(!line)
			goto done;

		p = line + cpp + 1;

		/* parse a colour definition */
		for(;;) {
			char nametype;
			char *colname;
			Uint32 rgb, pixel;

			SKIPSPACE(p);
			if(!*p) {
				error = "colour parse error";
				goto done;
			}
			nametype = *p;
			SKIPNONSPACE(p);
			SKIPSPACE(p);
			colname = p;
			SKIPNONSPACE(p);
			if(nametype == 's')
				continue;      /* skip symbolic colour names */

			if(!color_to_rgb(colname, p - colname, &rgb))
				continue;

			memcpy(nextkey, line, cpp);
			if(indexed) {
				SDL_Color *c = im_colors + index;
				c->r = (Uint8)(rgb >> 16);
				c->g = (Uint8)(rgb >> 8);
				c->b = (Uint8)(rgb);
				pixel = index;
			} else
				pixel = rgb;
			add_colorhash(colors, nextkey, cpp, pixel);
			nextkey += cpp;
			if(rgb == 0xffffffff)
				SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel);
			break;
		}
	}
Example #21
0
SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src)
{
	int start;
	SDL_Surface *surface = NULL;
	int width, height;
	int maxval, y, bpl;
	Uint8 *row;
	Uint8 *buf = NULL;
	char *error = NULL;
	Uint8 magic[2];
	int ascii;
	enum { PBM, PGM, PPM, PAM } kind;

#define ERROR(s) do { error = (s); goto done; } while(0)

	if ( !src ) {
		/* The error message has been set in SDL_RWFromFile */
		return NULL;
	}
	start = SDL_RWtell(src);

	SDL_RWread(src, magic, 2, 1);
	kind = magic[1] - '1';
	ascii = 1;
	if(kind >= 3) {
		ascii = 0;
		kind -= 3;
	}

	width = ReadNumber(src);
	height = ReadNumber(src);
	if(width <= 0 || height <= 0)
		ERROR("Unable to read image width and height");

	if(kind != PBM) {
		maxval = ReadNumber(src);
		if(maxval <= 0 || maxval > 255)
			ERROR("unsupported PNM format");
	} else
		maxval = 255;	/* never scale PBMs */

	/* binary PNM allows just a single character of whitespace after
	   the last parameter, and we've already consumed it */

	if(kind == PPM) {
		/* 24-bit surface in R,G,B byte order */
		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
					   0x000000ff, 0x0000ff00, 0x00ff0000,
#else
					   0x00ff0000, 0x0000ff00, 0x000000ff,
#endif
					   0);
	} else {
		/* load PBM/PGM as 8-bit indexed images */
		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 8,
					   0, 0, 0, 0);
	}
	if ( surface == NULL )
		ERROR("Out of memory");
	bpl = width * surface->format->BytesPerPixel;
	if(kind == PGM) {
		SDL_Color *c = surface->format->palette->colors;
		int i;
		for(i = 0; i < 256; i++)
			c[i].r = c[i].g = c[i].b = i;
		surface->format->palette->ncolors = 256;
	} else if(kind == PBM) {
		/* for some reason PBM has 1=black, 0=white */
		SDL_Color *c = surface->format->palette->colors;
		c[0].r = c[0].g = c[0].b = 255;
		c[1].r = c[1].g = c[1].b = 0;
		surface->format->palette->ncolors = 2;
		bpl = (width + 7) >> 3;
		buf = malloc(bpl);
		if(buf == NULL)
			ERROR("Out of memory");
	}
Sint64 u8file::ftell(){
	return SDL_RWtell(m_file);
}
static long sdl_tell_func(void *datasource)
{
    return (long)SDL_RWtell((SDL_RWops*)datasource);
}
Example #24
0
bool Serializer::writeRoomData() {
  // Write the enable status for the spots of all nodes of all rooms
  if (!SDL_WriteBE16(_rw, Control::instance().numRooms()))
    return false;

  for (Room *room : Control::instance().rooms()) {
    if (!SDL_WriteBE16(_rw, room->numNodes()))
      return false;

    if (room->hasNodes()) {
      room->beginIteratingNodes();

      do {
        Node *node = room->iterator();

        if (!SDL_WriteBE16(_rw, node->numSpots()))
          return false;

        if (node->hasSpots()) {
          node->beginIteratingSpots();

          do {
            if (!SDL_WriteU8(_rw, node->currentSpot()->isEnabled()))
              return false;
          } while (node->iterateSpots());
        }
      } while (room->iterateNodes());
    }
  }

  Room *room = Control::instance().currentRoom();

  // Write node number
  uint16_t nodeIdx = 0;
  if (room->hasNodes()) {
    room->beginIteratingNodes();
    do {
      if (room->iterator() == room->currentNode())
        break;

      nodeIdx++;
    } while (room->iterateNodes());
  }

  if (!SDL_WriteBE16(_rw, nodeIdx))
    return false;

  // Write camera angles
  int hAngle = CameraManager::instance().angleHorizontal();
  const std::string hAngleStr = std::to_string(hAngle);
  if (!SDL_WriteU8(_rw, hAngleStr.length()))
    return false;
  if (!SDL_RWwrite(_rw, hAngleStr.c_str(), hAngleStr.length(), 1))
    return false;

  int vAngle = CameraManager::instance().angleVertical();
  const std::string vAngleStr = std::to_string(vAngle);
  if (!SDL_WriteU8(_rw, vAngleStr.length()))
    return false;
  if (!SDL_RWwrite(_rw, vAngleStr.c_str(), vAngleStr.length(), 1))
    return false;

  float fov = CameraManager::instance().fieldOfView();
  const std::string fovStr = std::to_string(fov);
  if (!SDL_WriteU8(_rw, fovStr.length()))
    return false;
  if (!SDL_RWwrite(_rw, fovStr.c_str(), fovStr.length(), 1))
    return false;

  // Write audio states
  if (!SDL_WriteBE16(_rw, room->arrayOfAudios().size()))
    return false;

  for (Audio *audio : room->arrayOfAudios()) {
    if (!SDL_WriteU8(_rw, audio->state()))
      return false;
  }

  // Write timers
  int64_t timersPtr = SDL_RWtell(_rw);
  if (timersPtr < 0)
    return false;
  if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual number of timers
    return false;

  uint16_t numTimers = 0;
  for (const auto &timer : TimerManager::instance().timers()) {
    if (timer.type != DGTimerNormal || !timer.isEnabled ||
        (!timer.isLoopable && timer.hasTriggered))
      continue;

    double elapsed = TimerManager::instance().timeElapsed(timer);
    if (timer.trigger - elapsed > 0) {
      const std::string triggerStr = std::to_string(timer.trigger);
      if (!SDL_WriteU8(_rw, timer.isLoopable))
        return false;
      if (!SDL_WriteU8(_rw, triggerStr.length()))
        return false;
      if (!SDL_RWwrite(_rw, triggerStr.c_str(), triggerStr.length(), 1))
        return false;

      const std::string elapsedStr = std::to_string(elapsed);
      if (!SDL_WriteU8(_rw, elapsedStr.length()))
        return false;
      if (!SDL_RWwrite(_rw, elapsedStr.c_str(), elapsedStr.length(), 1))
        return false;

      lua_rawgeti(_L, LUA_REGISTRYINDEX, timer.luaHandler); // Push timer function to top of stack

      int64_t funcSizePtr = SDL_RWtell(_rw);
      if (funcSizePtr < 0)
        return false;
      if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual function size
        return false;

      int64_t beforeFuncPtr = SDL_RWtell(_rw);
      if (beforeFuncPtr < 0)
        return false;
      int errCode = lua_dump(_L, writeFunction, _rw);
      if (errCode != 0)
        return false;
      int64_t afterFuncPtr = SDL_RWtell(_rw);
      if (afterFuncPtr < 0)
        return false;

      uint16_t numBytesWritten = afterFuncPtr - beforeFuncPtr;
      if (SDL_RWseek(_rw, funcSizePtr, RW_SEEK_SET) < 0)
        return false;
      if (!SDL_WriteBE16(_rw, numBytesWritten))
        return false;

      if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end
        return false;

      numTimers++;
    }
  }

  if (SDL_RWseek(_rw, timersPtr, RW_SEEK_SET) < 0)
    return false;
  if (!SDL_WriteBE16(_rw, numTimers))
    return false;
  if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end
    return false;

  // Write control mode
  if (!SDL_WriteU8(_rw, Config::instance().controlMode))
    return false;

  return true;
}
Example #25
0
/* TODO: (Chase) dump frames into frameset instead of combining into one frame */
int IMG_LoadGIF_RW(SDL_RWops *src, IMG_File* dst)
{
    int start;
    unsigned char buf[16];
    unsigned char c;
    unsigned char localColorMap[3][MAXCOLORMAPSIZE];
    int grayScale;
    int useGlobalColormap;
    int bitPixel;
    int imageCount = 0;
    char version[4];
    int imageNumber = 1; /*<-- I believe this is what we want to control in order to change what frame to grab*/
    int successCount = 0;
	int w = 0;
	int i = 0;
	Uint32 color = 0; 
	SDL_Surface*image = NULL;
	SDL_Surface*nextImage = NULL;
	GifFrame frame;
	GifFrame* frames;
	
    if ( src == NULL ) {
		return 0;
    }
    start = SDL_RWtell(src);

    if (!ReadOK(src, buf, 6)) {
		IMG_SetError("error reading magic number");
        goto done;
    }
    if (strncmp((char *) buf, "GIF", 3) != 0) {
		IMG_SetError("not a GIF file");
        goto done;
    }
    strncpy(version, (char *) buf + 3, 3);
    version[3] = '\0';

    if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
		IMG_SetError("bad version number, not '87a' or '89a'");
        goto done;
    }
    frame.transparent = -1;
    frame.delayMs = -1;
    frame.inputFlag = -1;
    frame.disposal = 0;

    if (!ReadOK(src, buf, 7)) {
		IMG_SetError("failed to read screen descriptor");
        goto done;
    }
    GifScreen.Width = LM_to_uint(buf[0], buf[1]);
    GifScreen.Height = LM_to_uint(buf[2], buf[3]);
    GifScreen.BitPixel = 2 << (buf[4] & 0x07);
    GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
    GifScreen.Background = buf[5];
    GifScreen.AspectRatio = buf[6];

    if (BitSet(buf[4], LOCALCOLORMAP)) {	/* Global Colormap */
		if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap,
			&GifScreen.GrayScale)) {
			IMG_SetError("error reading global colormap");
	        goto done;
		}
    }
	    
    dbgout("GLOBAL BG COLOR: Index:%i RGB:%i,%i,%i\n", GifScreen.Background,
			GifScreen.ColorMap[CM_RED][GifScreen.Background],
			GifScreen.ColorMap[CM_GREEN][GifScreen.Background], 
			GifScreen.ColorMap[CM_BLUE][GifScreen.Background]);
	
	
	frames = (GifFrame*)malloc(sizeof(GifFrame));
	if (!frames) {
		IMG_SetError("Malloc Failed");
		goto done;
	}
	
    do { /* This loop goes through and reads every image and sends its data to ReadImage, if its the one we want (index 1) it'll output SDL_Surface*/
		/*
			What this SHOULD do...
			METHOD 1 (Lazy):
				Read every image, output an SDL_Surface into a vector
				After loop, count vector images, make a new image which has a w equal to the vector.size() * image width
				Render each image from the vector onto the new image, each one with an x offset of image width * index
				Free all surfaces in the vector, return the new combined one.
			METHOD 2 (hardcore):
				Read every image, count the number of images we get.
				Create a surface with a w equal to count * width
				Go back and read every images data, writing their pixels, leftmost to images x * index
			GENERAL PROBLEM:
				We have no delay info. We'd have to manually set the frame delay... However, this isn't a problem. =3
			Looks like we can have local layer color maps.. of course being able to do this in imageready is a whole other issue.
				But as far as we know.. maybe?
		*/
		
		if (!ReadOK(src, &c, 1)) {
		    IMG_SetError("EOF / read error on image data");
	        goto done;
		} else
			dbgout("%c", c);
			
		if (c == ';') {		/* GIF terminator -0x3b */
		    /*if (imageCount < imageNumber) {
				IMG_SetError("only %d image%s found in file",
					imageCount, imageCount > 1 ? "s" : "");
	            goto done;
		    }*/
		    break;
		}
		if (c == '!') {		/* Extension 0x21 */
		    if (!ReadOK(src, &c, 1)) {
				IMG_SetError("EOF / read error on extention function code");
	            goto done;
		    }
		    DoExtension(&frame, src, c);
		    continue;
		}
		if (c != ',') {		/* Image seperator - 0x2c */
		    continue;
		}
		++imageCount;

		if (!ReadOK(src, buf, 9)) {
		    IMG_SetError("couldn't read left/top/width/height");
			goto done;
		}
/*
Offset   Length   Contents
  0      1 byte   Image Separator (0x2c)
  1      2 bytes  Image Left Position
  3      2 bytes  Image Top Position
  5      2 bytes  Image Width
  7      2 bytes  Image Height
  8      1 byte   bit 0:    Local Color Table Flag (LCTF)
                  bit 1:    Interlace Flag
                  bit 2:    Sort Flag
                  bit 2..3: Reserved
                  bit 4..7: Size of Local Color Table: 2^(1+n)
         ? bytes  Local Color Table(0..255 x 3 bytes) if LCTF is one
         1 byte   LZW Minimum Code Size
[ // Blocks
         1 byte   Block Size (s)
œSx    (s)bytes  Image Data
]*
         1 byte   Block Terminator(0x00)
*/

		useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);

		frame.x = LM_to_uint(buf[0], buf[1]);
		frame.y = LM_to_uint(buf[2], buf[3]);
		
		dbgout("X:%i, Y:%i\n", frame.x, frame.y);

		bitPixel = 1 << ((buf[8] & 0x07) + 1);
		dbgout("Checkpoint\n");
		if (!useGlobalColormap) {
		    if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) {
				IMG_SetError("error reading local colormap");
	            goto done;
		    }
		    image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
				      LM_to_uint(buf[6], buf[7]),
				      bitPixel, localColorMap, grayScale,
				      BitSet(buf[8], INTERLACE),
				      0);
			if (image) color = SDL_MapRGB(image->format,
										localColorMap[CM_RED][frame.transparent], 
										localColorMap[CM_GREEN][frame.transparent], 
										localColorMap[CM_BLUE][frame.transparent]);
		} else {
		    image = ReadImage(src, LM_to_uint(buf[4], buf[5]),
				      LM_to_uint(buf[6], buf[7]),
				      GifScreen.BitPixel, GifScreen.ColorMap,
				      GifScreen.GrayScale, BitSet(buf[8], INTERLACE),
				      0); 
			if (image) color = SDL_MapRGB(image->format,
										GifScreen.ColorMap[CM_RED][frame.transparent], 
										GifScreen.ColorMap[CM_GREEN][frame.transparent], 
										GifScreen.ColorMap[CM_BLUE][frame.transparent]);
		}
		dbgout("Image: %p\n", image);
		if (image) {
			++successCount;
			/*image = convertTo32bit(image); */ /* transform to a 32 bit surface because I HATE palettes*/
			dbgout("Converted Image: %ix%i [%p]\n", image->w, image->h, image);
			if (image) {
			    if ( frame.transparent >= 0 ) {
			        SDL_SetColorKey(image, SDL_SRCCOLORKEY, frame.transparent);
			    }
			    /*if ( frame.transparent >= 0 ) {
			        SDL_SetColorKey(image, SDL_SRCCOLORKEY, color);
			        Uint8 r, g, b;
					SDL_GetRGB(color, image->format, &r, &g, &b);
					dbgout("Local Transparency: %i,%i,%i\n", r, g, b);
			    }*/
				/*Reallocate room for another image in the list*/
				frames = (GifFrame*)realloc(frames, successCount * sizeof(GifFrame));
				if (!frames) { /*realloc failed*/
					IMG_SetError("Realloc Failed");
			        goto done;
				}
				frame.surf = image;
				/* Copy the current state of the GifFrame before the next read loop */
				frames[successCount-1] = frame;
				/*int i = 0;
				while (i < successCount) {
					dbgout("Frames[%i]: %p\n", i, frames[i]);	
					i++;
				}*/
				
				image = NULL;
			}
		}
		
    } while (1); /*let the above ... goto's... handle it*/
    
    SDL_Frame* framesArray;
	if (successCount > 0) 
	{
		dbgout("Mallocing Frames %i\n", successCount);fflush(stdout);
		
		framesArray = IMG_MallocFrames(successCount);

		i = 0;
		
		//first frame
		image = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, 
										GifScreen.Height, 
										32, RMASK, GMASK, BMASK, 0);
				
		color = SDL_MapRGB(image->format,
							GifScreen.ColorMap[CM_RED][frames[0].transparent], 
							GifScreen.ColorMap[CM_GREEN][frames[0].transparent], 
							GifScreen.ColorMap[CM_BLUE][frames[0].transparent]);
		Uint8 r, g, b;
		SDL_GetRGB(color, image->format, &r, &g, &b);
		dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout);
		if (color != 0) /* Ignore 0,0,0 as the transparent color */
		{ 
			SDL_FillRect(image, NULL, color);
			SDL_SetColorKey(image, SDL_SRCCOLORKEY, color); /* use the first frames trans color */
		}

		while (i < successCount) /* render our surfs and clear */
		{
			if (image)
			{
				dbgout("Dimensions: %ix%i: %p\n", image->w, image->h, image);fflush(stdout);

				w = 0;

				SDL_Rect r2, r3; 
				
				dbgout("Adding Frames[%i]: %p Disposal:%i TransIndex: %i Delay: %i Input:%i\n", i, 
						frames[i].surf, frames[i].disposal, frames[i].transparent, frames[i].delayMs,
						frames[i].inputFlag);	fflush(stdout);
						
				/* Print out the overlay at its offset coordinates */
				r2.x = frames[i].x;
				r2.y = frames[i].y; 
				r2.w = frames[i].surf->w;
				r2.h = frames[i].surf->h;
				
				dbgout("Drawing at: %i,%i\n", r2.x, r2.y);fflush(stdout);
				if (SDL_BlitSurface(frames[i].surf, NULL, image, &r2)) 
				{
					/*something bad happened but ignore it for now. */
					dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout);
				}
				dbgout("Setting Crap\n");fflush(stdout);
				//add image to our frames list
				framesArray[i].surf = image;
				framesArray[i].delay = frames[i].delayMs * 10; //HACK: All observed gifs have a delay of say.. 7, which means 70ms.
				framesArray[i].key = NULL;
				
				dbgout("i+1 crap\n");fflush(stdout);
				/*what to do in frame[i+1] before rendering*/
				if (i + 1 < successCount)
				{
					//create next frame so we can do something to it
					nextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, GifScreen.Width, 
										GifScreen.Height, 
										32, RMASK, GMASK, BMASK, 0);
									
					color = SDL_MapRGB(nextImage->format,
										GifScreen.ColorMap[CM_RED][frames[0].transparent], 
										GifScreen.ColorMap[CM_GREEN][frames[0].transparent], 
										GifScreen.ColorMap[CM_BLUE][frames[0].transparent]);
					Uint8 r, g, b;
					SDL_GetRGB(color, nextImage->format, &r, &g, &b);
					dbgout("Final Transparency: %i,%i,%i\n", r, g, b);fflush(stdout);
					if (color != 0) /* Ignore 0,0,0 as the transparent color */
					{ 
						SDL_FillRect(nextImage, NULL, color);
						SDL_SetColorKey(nextImage, SDL_SRCCOLORKEY, color); /* use the first frames trans color */
					}
				
					dbgout("Disposal crap\n");fflush(stdout);
					switch (frames[i].disposal)
					{
						case DISPOSAL_PREVIOUSFRAME: /* 04h - Overwrite graphic with previous graphic */
							dbgout("Doing previous frame\n");fflush(stdout);
							r2.x = 0;
							r2.y = 0;
							r2.w = GifScreen.Width;
							r2.h = GifScreen.Height;
							SDL_BlitSurface(frames[0].surf, NULL, nextImage, &r2); //Since I'm lazy, and haven't seen many gifs use this, it'll just render the original frame
							break;
						case DISPOSAL_UNSPECIFIED: /* DISPOSAL_UNSPECIFIED 00h - Let the viewer decide */
							/*Drop down to donotdispose */
						case DISPOSAL_DONOTDISPOSE: /* 01h - Leave graphic there */
							dbgout("Doing nondispose\n");fflush(stdout);
							/*render a copy of the previous i-1 into i */
							
							r2.w = GifScreen.Width;
							r2.h = GifScreen.Height;
							r2.x = 0;
							r2.y = 0;
							/* r3 = src, r2 = dst */
							r3.w = GifScreen.Width;
							r3.h = GifScreen.Height;
							r3.x = 0;
							r3.y = 0;
							dbgout("r3:(%i,%i)%ix%i r2:(%i,%i)%ix%i\n", r3.x, r3.y, r3.w, r3.h, 
																	  r2.x, r2.y, r2.w, r2.h);fflush(stdout);

							if (SDL_BlitSurface(image, &r3, nextImage, &r2)) {
								dbgout("Drawing Failed: %s\n", IMG_GetError());fflush(stdout);
							}
							break;	
						default: /* This'll default to DISPOSAL_BGCOLORWIPE 
									02h - Overwrite graphic with background color 
									do nothing, next rect is empty already*/
							dbgout("Doing default %i\n", frames[i].disposal);fflush(stdout);
							break;
					}
					image = nextImage;
				}
			}
			i++;
		}
		
		i = 0;
		while (i < successCount) {
			SDL_FreeSurface(frames[i].surf);
			i++;
		}
		free(frames);
		frames = NULL;
	} else {
		image = NULL;
	}
	
done:
	if (frames) { /* We didn't complete successfully, handle any leaks */
		i = 0;
		while (i < successCount) {
			SDL_FreeSurface(frames[i].surf);
			i++;
		}
		free(frames);
		/*if (image) {
			SDL_FreeSurface(image);
			image = NULL; 
		}*/
	}
	
	/*if ( image == NULL ) {
        SDL_RWseek(src, start, SEEK_SET);
    }   */
		
	if (successCount > 0)
	{
		dst->frames = framesArray;
		dst->count = successCount;
		dst->format = IMG_FORMAT_GIF;
		return 1;
	}
	return 0;
		
    //return IMG_SurfaceToFrameset(image, sdlFrames, sdlFrameCount);
}
Example #26
0
static int AU_open(Sound_Sample *sample, const char *ext)
{
    Sound_SampleInternal *internal = sample->opaque;
    SDL_RWops *rw = internal->rw;
    int skip, hsize, i, bytes_per_second;
    struct au_file_hdr hdr;
    struct audec *dec;
    char c;

    /* read_au_header() will do byte order swapping. */
    BAIL_IF_MACRO(!read_au_header(rw, &hdr), "AU: bad header", 0);

    dec = malloc(sizeof *dec);
    BAIL_IF_MACRO(dec == NULL, ERR_OUT_OF_MEMORY, 0);
    internal->decoder_private = dec;

    if (hdr.magic == AU_MAGIC)
    {
        /* valid magic */
        dec->encoding = hdr.encoding;
        switch(dec->encoding)
        {
            case AU_ENC_ULAW_8:
                /* Convert 8-bit µ-law to 16-bit linear on the fly. This is
                   slightly wasteful if the audio driver must convert them
                   back, but µ-law only devices are rare (mostly _old_ Suns) */
                sample->actual.format = AUDIO_S16SYS;
                break;

            case AU_ENC_LINEAR_8:
                sample->actual.format = AUDIO_S8;
                break;

            case AU_ENC_LINEAR_16:
                sample->actual.format = AUDIO_S16MSB;
                break;

            default:
                free(dec);
                BAIL_MACRO("AU: Unsupported .au encoding", 0);
        } /* switch */

        sample->actual.rate = hdr.sample_rate;
        sample->actual.channels = hdr.channels;
        dec->remaining = hdr.data_size;
        hsize = hdr.hdr_size;

        /* skip remaining part of header (input may be unseekable) */
        for (i = HDR_SIZE; i < hsize; i++)
        {
            if (SDL_RWread(rw, &c, 1, 1) != 1)
            {
                free(dec);
                BAIL_MACRO(ERR_IO_ERROR, 0);
            } /* if */
        } /* for */
    } /* if */

    else if (__Sound_strcasecmp(ext, "au") == 0)
    {
        /*
         * A number of files in the wild have the .au extension but no valid
         * header; these are traditionally assumed to be 8kHz µ-law. Handle
         * them here only if the extension is recognized.
         */

        SNDDBG(("AU: Invalid header, assuming raw 8kHz µ-law.\n"));
        /* if seeking fails, we lose 24 samples. big deal */
        SDL_RWseek(rw, -HDR_SIZE, SEEK_CUR);
        dec->encoding = AU_ENC_ULAW_8;
        dec->remaining = (Uint32)-1; 		/* no limit */
        sample->actual.format = AUDIO_S16SYS;
        sample->actual.rate = 8000;
        sample->actual.channels = 1;
    } /* else if */

    else
    {
        free(dec);
        BAIL_MACRO("AU: Not an .AU stream.", 0);
    } /* else */    

    bytes_per_second = ( ( dec->encoding == AU_ENC_LINEAR_16 ) ? 2 : 1 )
        * sample->actual.rate * sample->actual.channels ;
    internal->total_time = ((dec->remaining == -1) ? (-1) :
                            ( ( dec->remaining / bytes_per_second ) * 1000 ) +
                            ( ( dec->remaining % bytes_per_second ) * 1000 /
                              bytes_per_second ) );

    sample->flags = SOUND_SAMPLEFLAG_CANSEEK;
    dec->total = dec->remaining;
    dec->start_offset = SDL_RWtell(rw);

    SNDDBG(("AU: Accepting data stream.\n"));
    return(1);
} /* AU_open */
static Sint64 sdl_tell_func(void *datasource)
{
    return SDL_RWtell((SDL_RWops*)datasource);
}
Example #28
0
long File::tell () const
{
	return SDL_RWtell(_file);
}
Example #29
0
static long LMM_Tell(struct MREADER *mr)
{
  struct LMM_MREADER *lmmmr = (struct LMM_MREADER *)mr;
  return SDL_RWtell(lmmmr->rw) - lmmmr->offset;
}
Example #30
0
static bool isJpg(const unsigned char * data, int length){
    /* TODO */
    return false;
#if 0
int start;
	int is_JPG;
	int in_scan;
	Uint8 magic[4];

	/* This detection code is by Steaphan Greene <*****@*****.**> */
	/* Blame me, not Sam, if this doesn't work right. */
	/* And don't forget to report the problem to the the sdl list too! */

	if ( !src )
		return 0;
	start = SDL_RWtell(src);
	is_JPG = 0;
	in_scan = 0;
	if ( SDL_RWread(src, magic, 2, 1) ) {
		if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) {
			is_JPG = 1;
			while (is_JPG == 1) {
				if(SDL_RWread(src, magic, 1, 2) != 2) {
					is_JPG = 0;
				} else if( (magic[0] != 0xFF) && (in_scan == 0) ) {
					is_JPG = 0;
				} else if( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) {
					/* Extra padding in JPEG (legal) */
					/* or this is data and we are scanning */
					SDL_RWseek(src, -1, RW_SEEK_CUR);
				} else if(magic[1] == 0xD9) {
					/* Got to end of good JPEG */
					break;
				} else if( (in_scan == 1) && (magic[1] == 0x00) ) {
					/* This is an encoded 0xFF within the data */
				} else if( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) {
					/* These have nothing else */
				} else if(SDL_RWread(src, magic+2, 1, 2) != 2) {
					is_JPG = 0;
				} else {
					/* Yes, it's big-endian */
					Uint32 start;
					Uint32 size;
					Uint32 end;
					start = SDL_RWtell(src);
					size = (magic[2] << 8) + magic[3];
					end = SDL_RWseek(src, size-2, RW_SEEK_CUR);
					if ( end != start + size - 2 ) is_JPG = 0;
					if ( magic[1] == 0xDA ) {
						/* Now comes the actual JPEG meat */
#ifdef	FAST_IS_JPEG
						/* Ok, I'm convinced.  It is a JPEG. */
						break;
#else
						/* I'm not convinced.  Prove it! */
						in_scan = 1;
#endif
					}
				}
			}
		}
	}
	SDL_RWseek(src, start, RW_SEEK_SET);
	return(is_JPG);
#endif
}