FLTK logo

[master] bc0d18c - Enable error and EOF check in class Fl_Image_Reader (#271)

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] bc0d18c - Enable error and EOF check in class Fl_Image_Reader (#271) "Albrecht Schlosser" Sep 25, 2021  
 
commit bc0d18c1bb6ce205f034161ea7816638b5d7f5b7
Author:     Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Sat Sep 25 19:33:22 2021 +0200
Commit:     Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Sat Sep 25 19:33:22 2021 +0200

    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.

 src/Fl_Image_Reader.cxx | 97 +++++++++++++++++++++++++++++++------------------
 src/Fl_Image_Reader.h   | 23 ++++++++++--
 2 files changed, 81 insertions(+), 39 deletions(-)

diff --git src/Fl_Image_Reader.cxx src/Fl_Image_Reader.cxx
index f9a886b..63cd145 100644
--- src/Fl_Image_Reader.cxx
+++ 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;
 }
diff --git src/Fl_Image_Reader.h src/Fl_Image_Reader.h
index 93f5edc..7d176ac 100644
--- src/Fl_Image_Reader.h
+++ src/Fl_Image_Reader.h
@@ -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
@@ -37,7 +37,9 @@ public:
   pIsFile(0), pIsData(0),
   pFile(0L), pData(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
@@ -45,7 +47,7 @@ public:
   int open(const char *filename);
 
   // 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
   ~Fl_Image_Reader();
@@ -68,6 +70,15 @@ public:
   // of the file or the original start address in memory
   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
   const char *name() { return pName; }
 
@@ -83,8 +94,14 @@ private:
   const unsigned char *pData;
   // a pointer to the start of the image data
   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
   char *pName;
+  // a flag to store EOF or error status
+  int pError;
 };
 
 #endif // FL_IMAGE_READER_H
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.