Enable error and EOF check in class Fl_Image_Reader (#271)
This is part 1 and a prerequisite for the fix of issue #271. It enables the user of this internal class (Fl_{BMP|GIF}_Image) to test for read errors and EOF (end of file) while reading. The method used to read data from memory got an optional third argument 'const long datasize = -1)' to limit the size of the memory block of data provided to the image reader. Default is -1 which means "unlimited" (backwards compatibility). Using only two arguments (w/o size limit) is deprecated and should only be done if the data size is not available.
This commit is contained in:
parent
0f12e96d13
commit
bc0d18c1bb
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Internal (Image) Reader class for the Fast Light Tool Kit (FLTK).
|
// Internal (Image) Reader class for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
// Copyright 2020 by Bill Spitzak and others.
|
// Copyright 2020-2021 by Bill Spitzak and others.
|
||||||
//
|
//
|
||||||
// This library is free software. Distribution and use rights are outlined in
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
// the file "COPYING" which should have been included with this file. If this
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
@ -50,12 +50,15 @@ int Fl_Image_Reader::open(const char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the reader for memory access, name is copied and stored
|
// Initialize the reader for memory access, name is copied and stored
|
||||||
int Fl_Image_Reader::open(const char *imagename, const unsigned char *data) {
|
int Fl_Image_Reader::open(const char *imagename, const unsigned char *data, const long datasize) {
|
||||||
if (imagename)
|
if (imagename)
|
||||||
pName = fl_strdup(imagename);
|
pName = fl_strdup(imagename);
|
||||||
if (data) {
|
if (data) {
|
||||||
pStart = pData = data;
|
pStart = pData = data;
|
||||||
pIsData = 1;
|
pIsData = 1;
|
||||||
|
if (datasize > 0) {
|
||||||
|
pEnd = pStart + datasize;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -73,60 +76,82 @@ Fl_Image_Reader::~Fl_Image_Reader() {
|
|||||||
|
|
||||||
// Read a single byte from memory or a file
|
// Read a single byte from memory or a file
|
||||||
uchar Fl_Image_Reader::read_byte() {
|
uchar Fl_Image_Reader::read_byte() {
|
||||||
|
if (error()) // don't read after read error or EOF
|
||||||
|
return 0;
|
||||||
if (pIsFile) {
|
if (pIsFile) {
|
||||||
return getc(pFile);
|
int ret = getc(pFile);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (feof(pFile))
|
||||||
|
pError = 1;
|
||||||
|
else if (ferror(pFile))
|
||||||
|
pError = 2;
|
||||||
|
else
|
||||||
|
pError = 3; // unknown error
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
} else if (pIsData) {
|
} else if (pIsData) {
|
||||||
return *pData++;
|
if (pData < pEnd)
|
||||||
} else {
|
return *pData++;
|
||||||
|
pError = 1; // EOF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
pError = 3; // undefined mode
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a 16-bit unsigned integer, LSB-first
|
// Read a 16-bit unsigned integer, LSB-first
|
||||||
unsigned short Fl_Image_Reader::read_word() {
|
unsigned short Fl_Image_Reader::read_word() {
|
||||||
unsigned char b0, b1; // Bytes from file
|
unsigned char b0, b1; // Bytes from file or memory
|
||||||
if (pIsFile) {
|
b0 = read_byte();
|
||||||
b0 = (uchar)getc(pFile);
|
b1 = read_byte();
|
||||||
b1 = (uchar)getc(pFile);
|
if (error())
|
||||||
return ((b1 << 8) | b0);
|
|
||||||
} else if (pIsData) {
|
|
||||||
b0 = *pData++;
|
|
||||||
b1 = *pData++;
|
|
||||||
return ((b1 << 8) | b0);
|
|
||||||
} else {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
return ((b1 << 8) | b0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a 32-bit unsigned integer, LSB-first
|
// Read a 32-bit unsigned integer, LSB-first
|
||||||
unsigned int Fl_Image_Reader::read_dword() {
|
unsigned int Fl_Image_Reader::read_dword() {
|
||||||
unsigned char b0, b1, b2, b3; // Bytes from file
|
unsigned char b0, b1, b2, b3; // Bytes from file or memory
|
||||||
if (pIsFile) {
|
b0 = read_byte();
|
||||||
b0 = (uchar)getc(pFile);
|
b1 = read_byte();
|
||||||
b1 = (uchar)getc(pFile);
|
b2 = read_byte();
|
||||||
b2 = (uchar)getc(pFile);
|
b3 = read_byte();
|
||||||
b3 = (uchar)getc(pFile);
|
if (error())
|
||||||
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
|
||||||
} else if (pIsData) {
|
|
||||||
b0 = *pData++;
|
|
||||||
b1 = *pData++;
|
|
||||||
b2 = *pData++;
|
|
||||||
b3 = *pData++;
|
|
||||||
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
|
||||||
} else {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a 32-bit signed integer, LSB-first
|
|
||||||
// int Fl_Image_Reader::read_long() -- implementation in header file
|
|
||||||
|
|
||||||
// Move the current read position to a byte offset from the beginning
|
// Move the current read position to a byte offset from the beginning
|
||||||
// of the file or the original start address in memory
|
// of the file or the original start address in memory.
|
||||||
|
// This clears the error flag if the position is valid.
|
||||||
void Fl_Image_Reader::seek(unsigned int n) {
|
void Fl_Image_Reader::seek(unsigned int n) {
|
||||||
if (pIsFile) {
|
if (pIsFile) {
|
||||||
fseek(pFile, n , SEEK_SET);
|
int ret = fseek(pFile, n , SEEK_SET);
|
||||||
|
if (ret < 0)
|
||||||
|
pError = 2; // read / position error
|
||||||
|
else
|
||||||
|
pError = 0;
|
||||||
|
return;
|
||||||
} else if (pIsData) {
|
} else if (pIsData) {
|
||||||
pData = pStart + n;
|
if (pStart + n <= pEnd)
|
||||||
|
pData = pStart + n;
|
||||||
|
else
|
||||||
|
pError = 2; // read / position error
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
// unknown mode (not initialized ?)
|
||||||
|
pError = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get the current read position as a byte offset from the
|
||||||
|
// beginning of the file or the original start address in memory
|
||||||
|
long Fl_Image_Reader::tell() const {
|
||||||
|
if (pIsFile) {
|
||||||
|
return ftell(pFile);
|
||||||
|
} else if (pIsData) {
|
||||||
|
return long(pData - pStart);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Internal (Image) Reader class for the Fast Light Tool Kit (FLTK).
|
// Internal (Image) Reader class for the Fast Light Tool Kit (FLTK).
|
||||||
//
|
//
|
||||||
// Copyright 2020 by Bill Spitzak and others.
|
// Copyright 2020-2021 by Bill Spitzak and others.
|
||||||
//
|
//
|
||||||
// This library is free software. Distribution and use rights are outlined in
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
// the file "COPYING" which should have been included with this file. If this
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
@ -37,7 +37,9 @@ public:
|
|||||||
pIsFile(0), pIsData(0),
|
pIsFile(0), pIsData(0),
|
||||||
pFile(0L), pData(0L),
|
pFile(0L), pData(0L),
|
||||||
pStart(0L),
|
pStart(0L),
|
||||||
pName(0L)
|
pEnd((const unsigned char *)(-1L)),
|
||||||
|
pName(0L),
|
||||||
|
pError(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Initialize the reader to access the file system, filename is copied
|
// Initialize the reader to access the file system, filename is copied
|
||||||
@ -45,7 +47,7 @@ public:
|
|||||||
int open(const char *filename);
|
int open(const char *filename);
|
||||||
|
|
||||||
// Initialize the reader for memory access, name is copied and stored
|
// Initialize the reader for memory access, name is copied and stored
|
||||||
int open(const char *imagename, const unsigned char *data);
|
int open(const char *imagename, const unsigned char *data, const long datasize = -1);
|
||||||
|
|
||||||
// Close and destroy the reader
|
// Close and destroy the reader
|
||||||
~Fl_Image_Reader();
|
~Fl_Image_Reader();
|
||||||
@ -68,6 +70,15 @@ public:
|
|||||||
// of the file or the original start address in memory
|
// of the file or the original start address in memory
|
||||||
void seek(unsigned int n);
|
void seek(unsigned int n);
|
||||||
|
|
||||||
|
// Get the current file or memory offset from the beginning
|
||||||
|
// of the file or the original start address in memory
|
||||||
|
long tell() const;
|
||||||
|
|
||||||
|
// Get the current EOF or error status of the file or data block
|
||||||
|
int error() const {
|
||||||
|
return pError;
|
||||||
|
}
|
||||||
|
|
||||||
// return the name or filename for this reader
|
// return the name or filename for this reader
|
||||||
const char *name() { return pName; }
|
const char *name() { return pName; }
|
||||||
|
|
||||||
@ -83,8 +94,14 @@ private:
|
|||||||
const unsigned char *pData;
|
const unsigned char *pData;
|
||||||
// a pointer to the start of the image data
|
// a pointer to the start of the image data
|
||||||
const unsigned char *pStart;
|
const unsigned char *pStart;
|
||||||
|
// a pointer to the end of image data if reading from memory, otherwise undefined
|
||||||
|
// note: currently (const unsigned char *)(-1L) if end of memory is not available
|
||||||
|
// ... which means "unlimited"
|
||||||
|
const unsigned char *pEnd;
|
||||||
// a copy of the name associated with this reader
|
// a copy of the name associated with this reader
|
||||||
char *pName;
|
char *pName;
|
||||||
|
// a flag to store EOF or error status
|
||||||
|
int pError;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FL_IMAGE_READER_H
|
#endif // FL_IMAGE_READER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user