jpg_loader: code refactoring

keep it clean and neat code add some TODO comments for the future tasks.

This also fixes potential data memory leak.
This commit is contained in:
Hermet Park 2021-07-09 17:37:58 +09:00 committed by Hermet Park
parent cc71ff43e5
commit aa1a43e3a2
2 changed files with 37 additions and 22 deletions

View file

@ -21,6 +21,7 @@
*/ */
#include <memory.h> #include <memory.h>
#include <turbojpeg.h>
#include "tvgLoaderMgr.h" #include "tvgLoaderMgr.h"
#include "tvgJpgLoader.h" #include "tvgJpgLoader.h"
@ -30,10 +31,10 @@
void JpgLoader::clear() void JpgLoader::clear()
{ {
tjFree(data); if (freeData) free(data);
data = NULL; data = nullptr;
pointer = NULL;
size = 0; size = 0;
freeData = false;
} }
/************************************************************************/ /************************************************************************/
@ -45,34 +46,41 @@ JpgLoader::JpgLoader()
jpegDecompressor = tjInitDecompress(); jpegDecompressor = tjInitDecompress();
} }
JpgLoader::~JpgLoader() JpgLoader::~JpgLoader()
{ {
if (data) tjFree(data); if (freeData) free(data);
tjDestroy(jpegDecompressor); tjDestroy(jpegDecompressor);
//This image is shared with raster engine.
tjFree(image); tjFree(image);
image = NULL;
} }
bool JpgLoader::open(const string& path) bool JpgLoader::open(const string& path)
{ {
clear(); clear();
bool success = false; auto jpegFile = fopen(path.c_str(), "rb");
FILE *jpegFile = NULL; if (!jpegFile) return false;
if ((jpegFile = fopen(path.c_str(), "rb")) == NULL) return false;
auto ret = false;
//determine size //determine size
if (fseek(jpegFile, 0, SEEK_END) < 0) goto finalize; if (fseek(jpegFile, 0, SEEK_END) < 0) goto finalize;
if (((size = ftell(jpegFile)) < 1)) goto finalize; if (((size = ftell(jpegFile)) < 1)) goto finalize;
if (fseek(jpegFile, 0, SEEK_SET)) goto finalize; if (fseek(jpegFile, 0, SEEK_SET)) goto finalize;
data = (unsigned char *) tjAlloc(size); data = (unsigned char *) malloc(size);
if (!data) goto finalize; if (!data) goto finalize;
if (fread(data, size, 1, jpegFile) < 1) goto failure; if (fread(data, size, 1, jpegFile) < 1) goto failure;
pointer = data; //FIXME: Decompress header here
success = true;
ret = true;
freeData = true;
goto finalize; goto finalize;
failure: failure:
@ -80,9 +88,10 @@ failure:
finalize: finalize:
fclose(jpegFile); fclose(jpegFile);
return success; return ret;
} }
bool JpgLoader::open(const char* data, uint32_t size, bool copy) bool JpgLoader::open(const char* data, uint32_t size, bool copy)
{ {
clear(); clear();
@ -91,24 +100,26 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy)
this->data = (unsigned char *) malloc(size); this->data = (unsigned char *) malloc(size);
if (!this->data) return false; if (!this->data) return false;
memcpy((unsigned char *)this->data, data, size); memcpy((unsigned char *)this->data, data, size);
this->pointer = this->data; freeData = true;
} else { } else {
this->pointer = (unsigned char *)data; this->data = (unsigned char *) data;
} }
this->size = size; this->size = size;
//FIXME: Decompress header here
return true; return true;
} }
bool JpgLoader::read() bool JpgLoader::read()
{ {
int width, height;
//decompress header //decompress header
int width, height;
int inSubsamp, inColorspace; int inSubsamp, inColorspace;
if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &inSubsamp, &inColorspace) < 0) return false; if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &inSubsamp, &inColorspace) < 0) return false;
//alloc image buffer
if (image) tjFree(image); if (image) tjFree(image);
image = (unsigned char *)tjAlloc(width * height * tjPixelSize[TJPF_BGRX]); image = (unsigned char *)tjAlloc(width * height * tjPixelSize[TJPF_BGRX]);
if (!image) return false; if (!image) return false;
@ -116,22 +127,25 @@ bool JpgLoader::read()
//decompress jpg image //decompress jpg image
if (tjDecompress2(jpegDecompressor, data, size, image, width, 0, height, TJPF_BGRX, 0) < 0) { if (tjDecompress2(jpegDecompressor, data, size, image, width, 0, height, TJPF_BGRX, 0) < 0) {
tjFree(image); tjFree(image);
image = NULL; image = nullptr;
return false; return false;
} }
vw = w = width; vw = w = width;
vh = h = height; vh = h = height;
return true; return true;
} }
bool JpgLoader::close() bool JpgLoader::close()
{ {
clear(); clear();
return true; return true;
} }
const uint32_t* JpgLoader::pixels() const uint32_t* JpgLoader::pixels()
{ {
return (const uint32_t*)image; return (const uint32_t*) image;
} }

View file

@ -22,8 +22,9 @@
#ifndef _TVG_JPG_LOADER_H_ #ifndef _TVG_JPG_LOADER_H_
#define _TVG_JPG_LOADER_H_ #define _TVG_JPG_LOADER_H_
#include <turbojpeg.h> using tjhandle = void*;
//TODO: Use Task?
class JpgLoader : public Loader class JpgLoader : public Loader
{ {
public: public:
@ -43,9 +44,9 @@ private:
tjhandle jpegDecompressor; tjhandle jpegDecompressor;
unsigned char* data = nullptr; unsigned char* data = nullptr;
const unsigned char* pointer = nullptr;
unsigned long size = 0;
unsigned char *image = nullptr; unsigned char *image = nullptr;
unsigned long size = 0;
bool freeData = false;
}; };
#endif //_TVG_JPG_LOADER_H_ #endif //_TVG_JPG_LOADER_H_