Browse Source

Images are now loaded from buffers.

David Piuva 3 years ago
parent
commit
eacc75aab6

+ 16 - 2
Source/DFPSR/api/imageAPI.cpp

@@ -28,6 +28,7 @@
 #include <cassert>
 #include <cassert>
 #include "imageAPI.h"
 #include "imageAPI.h"
 #include "drawAPI.h"
 #include "drawAPI.h"
+#include "fileAPI.h"
 #include "../image/draw.h"
 #include "../image/draw.h"
 #include "../image/internal/imageInternal.h"
 #include "../image/internal/imageInternal.h"
 #include "../image/stbImage/stbImageWrapper.h"
 #include "../image/stbImage/stbImageWrapper.h"
@@ -52,10 +53,23 @@ AlignedImageRgbaU8 dsr::image_create_RgbaU8_native(int32_t width, int32_t height
 	return AlignedImageRgbaU8(std::make_shared<ImageRgbaU8Impl>(width, height, packOrderIndex));
 	return AlignedImageRgbaU8(std::make_shared<ImageRgbaU8Impl>(width, height, packOrderIndex));
 }
 }
 
 
-// Loading and saving
+// Loading from data pointer
+OrderedImageRgbaU8 dsr::image_decode_RgbaU8(const SafePointer<uint8_t> data, int size, bool mustParse) {
+	return image_stb_decode_RgbaU8(data, size, mustParse);
+}
+// Loading from buffer
+OrderedImageRgbaU8 dsr::image_decode_RgbaU8(const Buffer& fileContent, bool mustParse) {
+	return image_decode_RgbaU8(buffer_getSafeData<uint8_t>(fileContent, "image file buffer"), buffer_getSize(fileContent), mustParse);
+}
+// Loading from file
 OrderedImageRgbaU8 dsr::image_load_RgbaU8(const String& filename, bool mustExist) {
 OrderedImageRgbaU8 dsr::image_load_RgbaU8(const String& filename, bool mustExist) {
-	return image_stb_load_RgbaU8(filename, mustExist);
+	//return image_stb_load_RgbaU8(filename, mustExist);
+	Buffer fileContent = file_loadBuffer(filename, mustExist);
+	return image_decode_RgbaU8(fileContent, mustExist);
 }
 }
+
+
+
 bool dsr::image_save(const ImageRgbaU8 &image, const String& filename) {
 bool dsr::image_save(const ImageRgbaU8 &image, const String& filename) {
 	return image_stb_save(image, filename);
 	return image_stb_save(image, filename);
 }
 }

+ 11 - 1
Source/DFPSR/api/imageAPI.h

@@ -135,8 +135,18 @@ namespace dsr {
 	float image_readPixel_tile(const ImageF32& image, int32_t x, int32_t y);
 	float image_readPixel_tile(const ImageF32& image, int32_t x, int32_t y);
 	ColorRgbaI32 image_readPixel_tile(const ImageRgbaU8& image, int32_t x, int32_t y);
 	ColorRgbaI32 image_readPixel_tile(const ImageRgbaU8& image, int32_t x, int32_t y);
 
 
-// Loading and saving
+// Loading
+	// Load an image from a file by giving the filename including folder path and extension.
 	OrderedImageRgbaU8 image_load_RgbaU8(const String& filename, bool mustExist = true);
 	OrderedImageRgbaU8 image_load_RgbaU8(const String& filename, bool mustExist = true);
+	// Load an image from a memory buffer, which can be loaded with file_loadBuffer to get the same result as loading directly from the file.
+	//   A convenient way of loading compressed images from larger files.
+	OrderedImageRgbaU8 image_decode_RgbaU8(const Buffer& fileContent, bool mustParse = true);
+	// A faster and more flexible way to load compressed images from memory.
+	// If you just want to point directly to a memory location to avoid allocating many small buffers, you can use a safe pointer and a size in bytes.
+	OrderedImageRgbaU8 image_decode_RgbaU8(const SafePointer<uint8_t> data, int size, bool mustParse = true);
+
+// Saving
+	// Save the image to the path specified by filename and return true iff the operation was successful.
 	bool image_save(const ImageRgbaU8 &image, const String& filename);
 	bool image_save(const ImageRgbaU8 &image, const String& filename);
 
 
 // Fill all pixels with a uniform color
 // Fill all pixels with a uniform color

+ 15 - 10
Source/DFPSR/image/stbImage/stbImageWrapper.cpp

@@ -7,15 +7,18 @@
 
 
 #include "stbImageWrapper.h"
 #include "stbImageWrapper.h"
 
 
-using namespace dsr;
+namespace dsr {
 
 
-OrderedImageRgbaU8 dsr::image_stb_load_RgbaU8(const String& filename, bool mustExist) {
+OrderedImageRgbaU8 image_stb_decode_RgbaU8(const SafePointer<uint8_t> data, int size, bool mustParse) {
+	#ifdef SAFE_POINTER_CHECKS
+		// If the safe pointer has debug information, use it to assert that size is within bound.
+		target.assertInside("image_stb_decode_RgbaU8 (data)", data.getUnsafe(), (size_t)size);
+	#endif
 	int width, height, bpp;
 	int width, height, bpp;
-	uint8_t *data = stbi_load(filename.toStdString().c_str(), &width, &height, &bpp, 4);
-	if (data == 0) {
-		if (mustExist) {
-			// TODO: Throw an optional runtime exception
-			printText("The image ", filename, " could not be loaded!\n");
+	uint8_t *rawPixelData = stbi_load_from_memory(data.getUnsafe(), size, &width, &height, &bpp, 4);
+	if (rawPixelData == nullptr) {
+		if (mustParse) {
+			throwError("An image could not be parsed!\n");
 		}
 		}
 		return OrderedImageRgbaU8(); // Return null
 		return OrderedImageRgbaU8(); // Return null
 	}
 	}
@@ -24,7 +27,7 @@ OrderedImageRgbaU8 dsr::image_stb_load_RgbaU8(const String& filename, bool mustE
 	// Copy the data
 	// Copy the data
 	int rowSize = width * 4;
 	int rowSize = width * 4;
 	int32_t targetStride = image_getStride(result);
 	int32_t targetStride = image_getStride(result);
-	const uint8_t *sourceRow = data;
+	const uint8_t *sourceRow = rawPixelData;
 	uint8_t* targetRow = image_dangerous_getData(result);
 	uint8_t* targetRow = image_dangerous_getData(result);
 	for (int32_t y = 0; y < height; y++) {
 	for (int32_t y = 0; y < height; y++) {
 		// Copy a row without touching the padding
 		// Copy a row without touching the padding
@@ -34,12 +37,14 @@ OrderedImageRgbaU8 dsr::image_stb_load_RgbaU8(const String& filename, bool mustE
 		sourceRow += rowSize;
 		sourceRow += rowSize;
 	}
 	}
 	// Free the unpadded image
 	// Free the unpadded image
-	free(data);
+	free((void*)rawPixelData);
 	return result;
 	return result;
 }
 }
 
 
-bool dsr::image_stb_save(const ImageRgbaU8 &image, const String& filename) {
+bool image_stb_save(const ImageRgbaU8 &image, const String& filename) {
 	// Remove all padding before saving to avoid crashing
 	// Remove all padding before saving to avoid crashing
 	ImageRgbaU8 unpadded = ImageRgbaU8(image_removePadding(image));
 	ImageRgbaU8 unpadded = ImageRgbaU8(image_removePadding(image));
 	return stbi_write_png(filename.toStdString().c_str(), image_getWidth(unpadded), image_getHeight(unpadded), 4, image_dangerous_getData(unpadded), image_getStride(unpadded)) != 0;
 	return stbi_write_png(filename.toStdString().c_str(), image_getWidth(unpadded), image_getHeight(unpadded), 4, image_dangerous_getData(unpadded), image_getStride(unpadded)) != 0;
 }
 }
+
+}

+ 1 - 1
Source/DFPSR/image/stbImage/stbImageWrapper.h

@@ -7,7 +7,7 @@
 
 
 namespace dsr {
 namespace dsr {
 
 
-OrderedImageRgbaU8 image_stb_load_RgbaU8(const String& filename, bool mustExist = true);
+OrderedImageRgbaU8 image_stb_decode_RgbaU8(const SafePointer<uint8_t> data, int size, bool mustParse = true);
 bool image_stb_save(const ImageRgbaU8 &image, const String& filename);
 bool image_stb_save(const ImageRgbaU8 &image, const String& filename);
 
 
 }
 }