summaryrefslogtreecommitdiff
path: root/src/Fl_GIF_Image.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/Fl_GIF_Image.cxx')
-rw-r--r--src/Fl_GIF_Image.cxx81
1 files changed, 62 insertions, 19 deletions
diff --git a/src/Fl_GIF_Image.cxx b/src/Fl_GIF_Image.cxx
index 91b8c13a5..4054eac77 100644
--- a/src/Fl_GIF_Image.cxx
+++ b/src/Fl_GIF_Image.cxx
@@ -81,35 +81,47 @@ typedef unsigned char uchar;
// Local reader class...
//
+/*
+ This class reads data chunks from a file or from memory in LSB-first
+ byte order.
+
+ TODO: GIFReader and BMPReader are very similar and should be combined to avoid
+ code duplication.
+ */
class GIFReader
{
public:
+ // Create the reader.
GIFReader() :
pIsFile(0), pIsData(0),
- pFile(0L), pData(0L), pStart(0L),
+ pFile(0L), pData(0L),
pName(0L)
{ }
+ // Initialize the reader to access the file system, filename is copied
+ // and stored.
int open(const char *filename) {
- if (filename)
- pName = strdup(filename);
- if ((pFile = fl_fopen(filename, "rb")) == NULL) {
+ if (!filename)
+ return -1;
+ pName = strdup(filename);
+ if ( (pFile = fl_fopen(filename, "rb")) == NULL ) {
return -1;
- } else {
- pIsFile = 1;
- return 0;
}
+ pIsFile = 1;
+ return 0;
}
+ // Initialize the reader for memory access, name is copied and stored
int open(const char *imagename, const unsigned char *data) {
if (imagename)
pName = strdup(imagename);
if (data) {
- pStart = pData = data;
+ pData = data;
pIsData = 1;
return 0;
} else {
return -1;
}
}
+ // Close and destroy the reader
~GIFReader() {
if (pIsFile && pFile) {
fclose(pFile);
@@ -117,6 +129,7 @@ public:
if (pName)
::free(pName);
}
+ // Read a single byte form memory or a file
uchar read_byte() {
if (pIsFile) {
return getc(pFile);
@@ -126,7 +139,7 @@ public:
return 0;
}
}
- // 'read_word()' - Read a 16-bit unsigned integer.
+ // Read a 16-bit unsigned integer, LSB-first
unsigned short read_word() {
unsigned char b0, b1; // Bytes from file
if (pIsFile) {
@@ -141,19 +154,27 @@ public:
return 0;
}
}
+ // return the name or filename for this reader
const char *name() { return pName; }
private:
+ // open() sets this if we read form a file
char pIsFile;
+ // open() sets this if we read form memory
char pIsData;
+ // a pointer to the opened file
FILE *pFile;
+ // a pointer to the current byte in memory
const unsigned char *pData;
- const unsigned char *pStart;
+ // a copy of the name associated with this reader
char *pName;
};
/**
- The constructor loads the named GIF image.
+ \brief The constructor loads the named GIF image.
+
+ IF a GIF is animated, Fl_GIF_Image will only read and display the first frame
+ of the animation.
The destructor frees all memory and server resources that are used by
the image.
@@ -162,6 +183,10 @@ private:
ERR_FILE_ACCESS if the file could not be opened or read, ERR_FORMAT if the
GIF format could not be decoded, and ERR_NO_IMAGE if the image could not
be loaded for another reason.
+
+ \param[in] filename a full path and name pointing to a valid GIF file.
+
+ \see Fl_GIF_Image::Fl_GIF_Image(const char *imagename, const unsigned char *data)
*/
Fl_GIF_Image::Fl_GIF_Image(const char *filename) :
Fl_Pixmap((char *const*)0)
@@ -171,32 +196,50 @@ Fl_GIF_Image::Fl_GIF_Image(const char *filename) :
Fl::error("Fl_GIF_Image: Unable to open %s!", filename);
ld(ERR_FILE_ACCESS);
} else {
- read(f);
+ load_gif_(f);
}
}
/**
- The constructor loads the named GIF image.
+ \brief The constructor loads a GIF image from memory.
+
+ Construct an image from a block of memory inside the application. Fluid offers
+ "binary Data" chunks as a great way to add image data into the C++ source code.
+ imagename can be NULL. If a name is given, the image is added to the list of
+ shared images and will be available by that name.
- \param[in] imagename the name of the GIF image
- \param[in] data a pointer to the GIF data in memory. There is no checking for buffer overruns
+ IF a GIF is animated, Fl_GIF_Image will only read and display the first frame
+ of the animation.
+
+ Use Fl_Image::fail() to check if Fl_GIF_Image failed to load. fail() returns
+ ERR_FILE_ACCESS if the file could not be opened or read, ERR_FORMAT if the
+ GIF format could not be decoded, and ERR_NO_IMAGE if the image could not
+ be loaded for another reason.
+
+ \param[in] imagename A name given to this image or NULL
+ \param[in] data Pointer to the start of the GIF image in memory. This code will not check for buffer overruns.
\see Fl_GIF_Image::Fl_GIF_Image(const char *filename)
+ \see Fl_Shared_Image
*/
Fl_GIF_Image::Fl_GIF_Image(const char *imagename, const unsigned char *data) :
Fl_Pixmap((char *const*)0)
{
GIFReader d;
if (d.open(imagename, data)==-1) {
- ld(ERR_FORMAT);
+ ld(ERR_FILE_ACCESS);
} else {
- read(d);
+ load_gif_(d);
}
}
-
-void Fl_GIF_Image::read(GIFReader &rdr)
+/*
+ This method reads GIF image data and creates an RGB or RGBA image. The GIF
+ format supports only 1 bit for alpha. To avoid code duplication, we use
+ a GIFReader that reads data from either a file or from memory.
+ */
+void Fl_GIF_Image::load_gif_(GIFReader &rdr)
{
char **new_data; // Data array