summaryrefslogtreecommitdiff
path: root/src/Fl_Image_Reader.cxx
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2021-09-25 19:33:22 +0200
committerAlbrecht Schlosser <albrechts.fltk@online.de>2021-09-25 19:33:22 +0200
commitbc0d18c1bb6ce205f034161ea7816638b5d7f5b7 (patch)
treede949877cd3e56856da658f88cf445457c60a257 /src/Fl_Image_Reader.cxx
parent0f12e96d138af1ea1fa371b858ee2094401621b7 (diff)
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.
Diffstat (limited to 'src/Fl_Image_Reader.cxx')
-rw-r--r--src/Fl_Image_Reader.cxx97
1 files changed, 61 insertions, 36 deletions
diff --git a/src/Fl_Image_Reader.cxx b/src/Fl_Image_Reader.cxx
index f9a886b0f..63cd145fd 100644
--- a/src/Fl_Image_Reader.cxx
+++ b/src/Fl_Image_Reader.cxx
@@ -1,7 +1,7 @@
//
// 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
// 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
-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)
pName = fl_strdup(imagename);
if (data) {
pStart = pData = data;
pIsData = 1;
+ if (datasize > 0) {
+ pEnd = pStart + datasize;
+ }
return 0;
} else {
return -1;
@@ -73,60 +76,82 @@ Fl_Image_Reader::~Fl_Image_Reader() {
// Read a single byte from memory or a file
uchar Fl_Image_Reader::read_byte() {
+ if (error()) // don't read after read error or EOF
+ return 0;
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) {
- return *pData++;
- } else {
+ if (pData < pEnd)
+ return *pData++;
+ pError = 1; // EOF
return 0;
}
+ pError = 3; // undefined mode
+ return 0;
}
// Read a 16-bit unsigned integer, LSB-first
unsigned short Fl_Image_Reader::read_word() {
- unsigned char b0, b1; // Bytes from file
- if (pIsFile) {
- b0 = (uchar)getc(pFile);
- b1 = (uchar)getc(pFile);
- return ((b1 << 8) | b0);
- } else if (pIsData) {
- b0 = *pData++;
- b1 = *pData++;
- return ((b1 << 8) | b0);
- } else {
+ unsigned char b0, b1; // Bytes from file or memory
+ b0 = read_byte();
+ b1 = read_byte();
+ if (error())
return 0;
- }
+ return ((b1 << 8) | b0);
}
// Read a 32-bit unsigned integer, LSB-first
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
+ b0 = read_byte();
+ b1 = read_byte();
+ b2 = read_byte();
+ b3 = read_byte();
+ if (error())
+ return 0;
+ return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+}
+
+// Move the current read position to a byte offset from the beginning
+// 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) {
if (pIsFile) {
- b0 = (uchar)getc(pFile);
- b1 = (uchar)getc(pFile);
- b2 = (uchar)getc(pFile);
- b3 = (uchar)getc(pFile);
- return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
+ int ret = fseek(pFile, n , SEEK_SET);
+ if (ret < 0)
+ pError = 2; // read / position error
+ else
+ pError = 0;
+ return;
} else if (pIsData) {
- b0 = *pData++;
- b1 = *pData++;
- b2 = *pData++;
- b3 = *pData++;
- return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
- } else {
- return 0;
+ if (pStart + n <= pEnd)
+ pData = pStart + n;
+ else
+ pError = 2; // read / position error
+ return;
}
+ // unknown mode (not initialized ?)
+ pError = 3;
}
-// 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
-// of the file or the original start address in memory
-void Fl_Image_Reader::seek(unsigned int n) {
+// 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) {
- fseek(pFile, n , SEEK_SET);
+ return ftell(pFile);
} else if (pIsData) {
- pData = pStart + n;
+ return long(pData - pStart);
}
+ return 0;
}