123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/platform.h"
- #include "core/stream/fileStream.h"
- #include "core/util/path.h"
- #include "gfx/bitmap/gBitmap.h"
- // This must come after our headers due to a conflicting definition of VoidPtr
- #include "lungif/gif_lib.h"
- using namespace Torque;
- static bool sReadGIF(Stream &stream, GBitmap *bitmap);
- static bool sWriteGIF(GBitmap *bitmap, Stream &stream, U32 compressionLevel);
- static struct _privateRegisterGIF
- {
- _privateRegisterGIF()
- {
- GBitmap::Registration reg;
- reg.extensions.push_back( "gif" );
- reg.readFunc = sReadGIF;
- reg.writeFunc = sWriteGIF;
- GBitmap::sRegisterFormat( reg );
- }
- } sStaticRegisterGIF;
- //-------------------------------------- Replacement I/O for standard LIBjpeg
- // functions. we don't wanna use
- // FILE*'s...
- static S32 gifReadDataFn(GifFileType *gifinfo, GifByteType *data, S32 length)
- {
- Stream *stream = (Stream*)gifinfo->UserData;
- AssertFatal(stream != NULL, "gifReadDataFn::No stream.");
- int pos = stream->getPosition();
- if (stream->read(length, data))
- return length;
- if (stream->getStatus() == Stream::EOS)
- return (stream->getPosition()-pos);
- else
- return 0;
- }
- //--------------------------------------
- #if 0
- // CodeReview - until we can write these, get rid of warning by disabling method.
- static S32 gifWriteDataFn(GifFileType *gifinfo, GifByteType *data, S32 length)
- {
- Stream *stream = (Stream*)gifinfo->UserData;
- AssertFatal(stream != NULL, "gifWriteDataFn::No stream.");
- if (stream->write(length, data))
- return length;
- else
- return 0;
- }
- #endif
- //--------------------------------------
- static bool sReadGIF( Stream &stream, GBitmap *bitmap )
- {
- GifFileType *gifinfo = DGifOpen( (void*)&stream, gifReadDataFn);
- if (!gifinfo)
- return false;
- GifRecordType recordType;
- do
- {
- if (DGifGetRecordType(gifinfo, &recordType) == GIF_ERROR)
- break;
- if (recordType == IMAGE_DESC_RECORD_TYPE)
- {
- if (DGifGetImageDesc(gifinfo) == GIF_ERROR)
- break;
- GFXFormat format = (gifinfo->SBackGroundColor == 0 ) ? GFXFormatR8G8B8 : GFXFormatR8G8B8A8;
- bitmap->allocateBitmap(gifinfo->SWidth, gifinfo->SHeight, false, format);
- // Assume no transparency until proven otherwise
- bitmap->setHasTransparency(false);
- U32 gwidth = gifinfo->Image.Width ? gifinfo->Image.Width : bitmap->getWidth();
- U32 gheight= gifinfo->Image.Height ? gifinfo->Image.Height : bitmap->getHeight();
- U32 gifSize = gwidth * gheight;
- U8 *data = new U8[gifSize];
- if (DGifGetLine(gifinfo, data, gifSize) != GIF_ERROR)
- {
- // use the global or local color table ?
- GifColorType *color = NULL;
- if (gifinfo->Image.ColorMap)
- color = gifinfo->Image.ColorMap->Colors;
- else if (gifinfo->SColorMap)
- color = gifinfo->SColorMap->Colors;
- if (color)
- {
- U8 *dst = bitmap->getAddress(gifinfo->Image.Left, gifinfo->Image.Top);
- U8 *src = data;
- U32 right = gifinfo->Image.Left + gwidth;
- U32 bottom = gifinfo->Image.Top + gheight;
- U32 next = (bitmap->getWidth() - gwidth) * bitmap->getBytesPerPixel();
- if (format == GFXFormatR8G8B8A8)
- {
- for (U32 y=gifinfo->Image.Top; y<bottom; y++)
- {
- for (U32 x=gifinfo->Image.Left; x<right; x++, src++)
- {
- if (*src == gifinfo->SBackGroundColor)
- {
- // this is a transparent pixel
- dst[0] = 0; // red
- dst[1] = 0; // green
- dst[2] = 0; // blue
- dst[3] = 0; // alpha
- bitmap->setHasTransparency(true);
- }
- else
- {
- dst[0] = color[*src].Red;
- dst[1] = color[*src].Green;
- dst[2] = color[*src].Blue;
- dst[3] = 0; // alpha
- }
- dst += bitmap->getBytesPerPixel();
- }
- dst += next;
- }
- }
- else
- {
- for (U32 y=gifinfo->Image.Top; y<bottom; y++)
- {
- for (U32 x=gifinfo->Image.Left; x<right; x++, src++)
- {
- dst[0] = color[*src].Red;
- dst[1] = color[*src].Green;
- dst[2] = color[*src].Blue;
- dst += bitmap->getBytesPerPixel();
- }
- dst += next;
- }
- }
- delete [] data;
- DGifCloseFile(gifinfo);
- return true;
- }
- }
- // failure
- delete [] data;
- break;
- }
- else if (recordType == EXTENSION_RECORD_TYPE)
- {
- GifByteType *extension;
- S32 extCode;
- // Skip any extension blocks in file
- if (DGifGetExtension(gifinfo, &extCode, &extension) != GIF_ERROR)
- {
- while (extension != NULL)
- {
- if (DGifGetExtensionNext(gifinfo, &extension) == GIF_ERROR)
- {
- return false;
- }
- }
- }
- else
- {
- return false;
- }
- }
- // There used to be a break right here. This caused the while condition to
- // never get processed, and so it never looped through all the records in
- // the GIF. I took a quick peek back at TGB and TGE histories and I am not
- // sure where this change got made, but I can't figure out why the loading
- // worked at all, ever, with that break in there. The only case I can think
- // of is if the first record in the GIF was the bitmap data.
- // [6/6/2007 Pat]
- }while (recordType != TERMINATE_RECORD_TYPE);
- DGifCloseFile(gifinfo);
- return true;
- }
- //--------------------------------------------------------------------------
- static bool sWriteGIF(GBitmap *bitmap, Stream &stream, U32 compressionLevel)
- {
- TORQUE_UNUSED( bitmap );
- TORQUE_UNUSED( stream );
- TORQUE_UNUSED( compressionLevel );
- return false;
- }
|