NDEVR
API Documentation
ImageFactory.h
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Design
28File: ImageFactory
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include "DLLInfo.h"
34#include <NDEVR/Dictionary.h>
35#include <NDEVR/String.h>
36#include <NDEVR/LABColor.h>
37#include <NDEVR/File.h>
38#include <NDEVR/RWLock.h>
39#include <NDEVR/UUID.h>
40#include <NDEVR/Pointer.h>
41namespace NDEVR
42{
43 class RLock;
44 class FileFormat;
55
59 struct NDEVR_DESIGN_API ImageCacheData
60 {
65 : modified_time(Time::SystemTime())
66 {}
67
68 //void readFromFile(StringView format_extension = StringView());
75 public:
84 Time modified_time = Constant<Time>::Invalid;
85 bool has_transparency = true;
87 };
88
92 struct ImageReadPointer : public ConstPointer<ImageCacheData>
93 {
98 : lock(nullptr)
99 {}
100
105 : ConstPointer<ImageCacheData>(d)
106 , lock(d->lock)
107 {}
108 private:
109 RLock lock;
110 };
111
115 struct ImageWritePointer : public DynamicPointer<ImageCacheData>
116 {
121 : lock(nullptr)
122 {}
123
127 ImageWritePointer(const DynamicPointer<ImageCacheData>& d)
128 : DynamicPointer<ImageCacheData>(d)
129 , lock(d->lock)
130 {}
131 private:
132 WLock lock;
133 };
134
139 {
140 public:
145 virtual UUID id() const = 0;
151 virtual void getSupportedFormats(AlocatingAlignedBuffer<FileFormat, 64>& formats, bool is_read) const = 0;
157 virtual bool canRead(StringView format) const = 0;
163 virtual bool canRead(const File& file) const = 0;
169 virtual bool canWrite(StringView format) const = 0;
175 virtual bool getMetaData(ImageCacheData&) { return false; };
181 virtual bool getUncompressed(ImageCacheData&) { return false; };
188 virtual bool getCompressed(ImageCacheData&, StringView) { return false; };
193 virtual bool hasTransparency(ImageCacheData&) { return false; };
198 virtual bool getSize(ImageCacheData&) { return false; };
203 virtual StringView compressionFormat(const uint01*, uint04) { return StringView(); };
204 };
205
210 class NDEVR_DESIGN_API ImageFactory
211 {
212 public:
219 void addImageFile(const StringView& id, const File& file, bool clear_other);
226 void addImageUncompressed(const StringView& id, const Buffer<uint01>& uncompressed, bool clear_other);
234 void addImageUncompressed(const StringView& id, const Buffer<uint01>& uncompressed, const Vector<2, uint04>& size, bool clear_other);
242 void addImageCompressed(const StringView& id, const StringView& extension, const Buffer<uint01>& compressed, bool clear_other);
251 void addImageCompressed(const StringView& id, const StringView& extension, const Buffer<uint01>& compressed, const Vector<2, uint04>& size, bool clear_other);
258 void addImageCompressed(const StringView& id, const Buffer<uint01>& compressed, bool clear_other);
264
270 void writeToFile(const StringView& id, const File& file);
277 void convertDirectory(const File& directory, const StringView& from_ext, const StringView& to_ext);
283 void copyImage(const StringView& id_destination, const StringView& id_source);
291 void convertColorTheme(const Buffer<std::pair<LABColor, LABColor>>& color, String& image, bool preserve_brightness, bool preserve_alpha);
297 Time modifiedTime(const StringView& id) const;
303 bool hasImage(const StringView& id) const;
316 ImageReadPointer getUncompressed(const StringView& id, bool ensure_valid_transparancy = false);
323 ImageReadPointer getCompressed(const StringView& id, StringView default_extension = ".png");
344 String optimizedWriteFileName(const StringView& id, const Buffer<String>& optional_extensions = Buffer<String>());
367 bool canRead(const File& file);
372 void setWriteQuality(fltp08 quality);
378 virtual void getSupportedFormats(AlocatingAlignedBuffer<FileFormat, 64>& formats, bool is_read) const;
405 void removeFormatHandler(const UUID& handler);
406
413 bool readFromFile(ImageCacheData& data, StringView format_extension = StringView());
448 public:
461 static void Resize(const Buffer<uint01>& input, const Vector<2, uint04>& in_size, const Vector<2, uint04>& out_size, Buffer<uint01>& output);
470 static void WriteToFile(const uint01* data, Vector<2, uint04> size, uint04 px_size, const File& file, fltp08 write_quality = 1.0);
480 static void ReadJPG(const uint01* input, uint04 input_length, uint01* buffer, bool has_alpha, uint04 dst_line_span, const Vector<2, uint04>& offset);
490 static void RemoveFormatHandler(const UUID& handler);
491 protected:
495 mutable RWLock m_lock;
496 protected:
498 };
499
503 class NDEVR_DESIGN_API ImageData
504 {
505 public:
511 ImageData(const StringView& id, ImageFactory& image_factory);
516 ImageData(const ImageData& data);
521 ImageData(ImageData&& data) noexcept;
530 [[nodiscard]] ImageReadPointer getUncompressed() const;
536 [[nodiscard]] ImageReadPointer getCompressed(const String& default_image_format) const;
541 [[nodiscard]] ImageReadPointer size() const;
546 [[nodiscard]] Time modifiedTime() const;
551 [[nodiscard]] StringView compressionFormat() const;
552 protected:
554 const String m_id;
555 };
556}
557
558
559
The equivelent of std::vector but with a bit more control.
Definition Buffer.hpp:58
A hash-based key-value store, useful for quick associative lookups.
Definition Dictionary.h:64
Provides a modifiable pointer that has shared ownership of a dynamically allocated object.
Definition Pointer.hpp:356
Data that describes a particular file format and how to use the format with the program.
Definition FileFormat.h:45
Logic for reading or writing to a file as well as navigating filesystems or other common file operati...
Definition File.h:53
ImageData(const ImageData &data)
Copy constructor.
ImageReadPointer getUncompressed() const
Retrieves the uncompressed (raw ARGB) pixel data for this image from the factory.
ImageData(ImageData &&data) noexcept
Move constructor.
StringView compressionFormat() const
Returns the compression format extension of this image's compressed data.
ImageReadPointer getCompressed(const String &default_image_format) const
Retrieves the compressed data for this image in the specified format.
Time modifiedTime() const
Returns the last modification time of this image.
ImageData(const StringView &id, ImageFactory &image_factory)
Constructs an ImageData referencing a specific image in the given factory.
const String m_id
The unique string identifier for this image within the factory.
ImageReadPointer size() const
Retrieves the image dimensions without fully decompressing the data.
ImageFactory & m_image_factory
Reference to the owning ImageFactory managing this image's data.
~ImageData()
Destructor.
The core class for reading/writing and storing images in an optimized way.
bool canRead(const File &file)
Checks whether any registered handler can read the given file.
static void ReadJPG(const uint01 *input, uint04 input_length, uint01 *buffer, bool has_alpha, uint04 dst_line_span, const Vector< 2, uint04 > &offset)
Decodes JPEG data from a memory buffer into a raw pixel buffer.
Dictionary< String, DynamicPointer< ImageCacheData > > cachedData() const
Returns a copy of the internal cache dictionary mapping image IDs to their cache data.
ImageReadPointer getUncompressed(const StringView &id, bool ensure_valid_transparancy=false)
Retrieves the uncompressed (raw ARGB) pixel data for the cached image.
bool hasImage(const StringView &id) const
Checks whether an image with the given identifier exists in the cache.
Dictionary< UUID, ImageFormatHandler * > m_format_handlers
Instance-level registered format handlers keyed by UUID.
void readFromBMP(ImageCacheData &data)
Reads image data from a BMP-formatted source into the cache data.
virtual void getSupportedFormats(AlocatingAlignedBuffer< FileFormat, 64 > &formats, bool is_read) const
Populates a buffer with all file formats supported by this factory and its handlers.
bool hasTransparency(ImageCacheData &data)
Determines whether the image truly contains transparent pixels (not just an alpha channel).
void addImageUncompressed(const StringView &id, const Buffer< uint01 > &uncompressed, bool clear_other)
Adds an uncompressed (raw ARGB) image to the cache.
ImageReadPointer getCompressed(const StringView &id, StringView default_extension=".png")
Retrieves the compressed data for the cached image in its current or default format.
static void Resize(const Buffer< uint01 > &input, const Vector< 2, uint04 > &in_size, const Vector< 2, uint04 > &out_size, Buffer< uint01 > &output)
Resizes raw pixel data from one resolution to another using bilinear or nearest-neighbor sampling.
void addImageUncompressed(const StringView &id, const Buffer< uint01 > &uncompressed, const Vector< 2, uint04 > &size, bool clear_other)
Adds an uncompressed (raw ARGB) image with explicit dimensions to the cache.
ImageReadPointer getMetaData(const StringView &id)
Retrieves metadata for the cached image, reading it from the source if necessary.
static FileFormat PNGFormat()
Creates and returns a FileFormat descriptor for the PNG image format.
void handleMetaData(ImageCacheData &data)
Reads and processes metadata (e.g., EXIF) from the image data using registered handlers.
bool readFromCompressed(ImageCacheData &data)
Reads image data from the compressed_data buffer in the cache data using registered handlers.
void copyImage(const StringView &id_destination, const StringView &id_source)
Copies cached image data from one identifier to another.
void addFormatHandler(ImageFormatHandler *handler)
Registers a format handler with this ImageFactory instance.
Time modifiedTime(const StringView &id) const
Returns the last modification time of the cached image.
ImageReadPointer getCompressedInFormat(const StringView &id, const Buffer< StringView > &acceptable_formats)
Retrieves the compressed data for the cached image in one of the acceptable formats.
static ImageFactory & DefaultFactory()
Returns the singleton default ImageFactory instance.
ImageReadPointer getSize(const StringView &id)
Retrieves the image dimensions without fully decompressing the image data.
static void AddFormatHandler(ImageFormatHandler *handler)
Registers a format handler with the global static handler registry, available to all ImageFactory ins...
bool determineCompressionFormat(ImageCacheData &data)
Attempts to determine the compression format of the image's compressed data by inspecting its header ...
StringView compressionFormat(const StringView &id)
Returns the compression format extension of the cached image's compressed data.
ImageReadPointer getCompressedInFormat(const StringView &id, const StringView &extension)
Retrieves the compressed data for the cached image, converting to a specific format.
static void RemoveFormatHandler(const UUID &handler)
Removes a format handler from the global static handler registry.
void addImageFile(const StringView &id, const File &file, bool clear_other)
Adds an image to the cache by reading from a file on disk.
void addImageCompressed(const StringView &id, const Buffer< uint01 > &compressed, bool clear_other)
Adds a compressed image to the cache, auto-detecting the compression format.
void addImageCompressed(const StringView &id, const StringView &extension, const Buffer< uint01 > &compressed, const Vector< 2, uint04 > &size, bool clear_other)
Adds a compressed image with a known format extension and explicit dimensions to the cache.
void convertDirectory(const File &directory, const StringView &from_ext, const StringView &to_ext)
Converts all images in a directory from one format to another.
static Dictionary< UUID, ImageFormatHandler * > s_format_handlers
Global static registry of format handlers shared across all ImageFactory instances.
void clearAllImageData(const StringView &id)
Removes all cached data (compressed, decompressed, metadata) for the given image.
ImageWritePointer getEditableData(const StringView &id)
Returns a writable pointer to the image cache data with a write lock acquired.
bool readFromFile(ImageCacheData &data, StringView format_extension=StringView())
Reads image data from the file referenced in the cache data.
ImageReadPointer getReadOnlyData(const StringView &id) const
Returns a read-only pointer to the image cache data with a read lock acquired.
void removeFormatHandler(const UUID &handler)
Removes a previously registered format handler by its UUID.
void addImageCompressed(const StringView &id, const StringView &extension, const Buffer< uint01 > &compressed, bool clear_other)
Adds a compressed image with a known format extension to the cache.
fltp08 m_write_quality
Default write quality for compressed output (0.0 to 1.0).
RWLock m_lock
Read-write lock protecting access to the cache and handler dictionaries.
void setWriteQuality(fltp08 quality)
Sets the quality level used when writing compressed images (e.g., JPEG quality).
void convertColorTheme(const Buffer< std::pair< LABColor, LABColor > > &color, String &image, bool preserve_brightness, bool preserve_alpha)
Remaps the colors of a cached image using LAB color space substitutions.
String optimizedWriteFileName(const StringView &id, const Buffer< String > &optional_extensions=Buffer< String >())
Determines the optimal file name and extension for writing the image to disk.
const Buffer< uint01 > & calculateAndGetDecompressed(ImageCacheData &data)
Ensures the decompressed data is available, decompressing if necessary, and returns it.
void writeToFile(const StringView &id, const File &file)
Writes the cached image to a file on disk.
Dictionary< String, DynamicPointer< ImageCacheData > > m_cached_data
Cache mapping image identifiers to their associated data.
static void WriteToFile(const uint01 *data, Vector< 2, uint04 > size, uint04 px_size, const File &file, fltp08 write_quality=1.0)
Writes raw pixel data to a file on disk in the format determined by the file extension.
Can be used to add functionality to the ImageFactory.
virtual StringView compressionFormat(const uint01 *, uint04)
Tries to determine what the format is of the image's compressed_data field.
virtual bool hasTransparency(ImageCacheData &)
Calculates whether the image truly has transparancy (not just a transparancy channel).
virtual bool getCompressed(ImageCacheData &, StringView)
Compresses the image into the specified format and populates the compressed_data field.
virtual bool canRead(StringView format) const =0
Checks whether this handler can read the given format extension.
virtual bool getUncompressed(ImageCacheData &)
Decompresses the image and populates the decompressed_data field of the cache data.
virtual bool getMetaData(ImageCacheData &)
Reads metadata (e.g., EXIF data) from the image and populates it in the cache data.
virtual void getSupportedFormats(AlocatingAlignedBuffer< FileFormat, 64 > &formats, bool is_read) const =0
Populates a buffer with the file formats this handler supports.
virtual UUID id() const =0
Returns the unique identifier for this format handler.
virtual bool getSize(ImageCacheData &)
Calculates the size of the image, if possible.
virtual bool canWrite(StringView format) const =0
Checks whether this handler can write the given format extension.
virtual bool canRead(const File &file) const =0
Checks whether this handler can read the given file.
Used to lock a particular variable for reading.
Definition RWLock.h:157
A readers-writer lock allowing concurrent reads or exclusive writes.
Definition RWLock.h:49
The core String View class for the NDEVR API.
Definition StringView.h:58
The core String class for the NDEVR API.
Definition String.h:95
Represents a timestamp with utilities for manipulation and conversion.
Definition Time.h:62
A universally unique identifier (UUID) is a 128-bit number used to identify information in computer s...
Definition UUID.h:61
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
A point in N-dimensional space, used primarily for spatial location information.
Definition Vertex.hpp:44
Used to lock a particular variable for writing.
Definition RWLock.h:272
The primary namespace for the NDEVR SDK.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
@ file
The source file path associated with this object.
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...
Holds cached image data including compressed and decompressed pixel buffers, file references,...
Vector< 2, uint04 > size
Image dimensions (width, height) in pixels.
Time modified_time
Last modification time of this cache entry.
RWLock lock
Read-write lock for thread-safe access to this cache entry.
ImageCacheData()
Constructs an ImageCacheData and sets modified_time to the current system time.
Buffer< uint01 > compressed_data
In-memory compressed image data (e.g., JPEG, PNG bytes).
ImageCacheData & operator=(const ImageCacheData &data)
Assigns the contents of another ImageCacheData to this one.
ImageMetaData metadata
Metadata associated with this image (location, orientation, etc.).
String compression_format
The file extension or format identifier of the compressed data (e.g., ".png").
bool has_calculated_transparency
Whether transparency has been explicitly determined (vs. assumed).
bool has_transparency
Whether the image contains transparent pixels.
String name
Display name or identifier for this image.
Buffer< uint01 > decompressed_data
Raw decompressed pixel data in ARGB 32-bit format.
File file
File reference for the on-disk image source, if applicable.
Stores metadata associated with an image, such as geolocation, orientation, and creation time.
Vector< 3, Angle< fltp08 > > orientation
Orientation (roll, pitch, yaw) of the camera when the image was captured.
Vertex< 3, fltp08 > lat_lon_location
Geographic location (latitude, longitude, altitude) where the image was captured.
Time creation_time
Timestamp when the image was originally created.
bool has_been_read
Whether the metadata has been read from the image source.
A read-only smart pointer to ImageCacheData that acquires a read lock on construction.
ImageReadPointer()
Default constructor.
ImageReadPointer(const DynamicPointer< ImageCacheData > &d)
Constructs a read pointer from a DynamicPointer and acquires a read lock.
A writable smart pointer to ImageCacheData that acquires a write lock on construction.
ImageWritePointer(const DynamicPointer< ImageCacheData > &d)
Constructs a write pointer from a DynamicPointer and acquires a write lock.
ImageWritePointer()
Default constructor.