Enforce a limit of 400 million pixels, 2GB file size
This commit is contained in:
parent
11dbe1e6aa
commit
2f255c7aff
18
README.md
18
README.md
@ -7,8 +7,6 @@ the documentation.
|
|||||||
|
|
||||||
More info at https://phoboslab.org/log/2021/11/qoi-fast-lossless-image-compression
|
More info at https://phoboslab.org/log/2021/11/qoi-fast-lossless-image-compression
|
||||||
|
|
||||||
⚠️ Please note that this library is not yet ready to deal with untrusted input.
|
|
||||||
|
|
||||||
⚠️ 2021.11.30 – the file format is not yet finalized. We're still working to fix
|
⚠️ 2021.11.30 – the file format is not yet finalized. We're still working to fix
|
||||||
some smaller issues. The final specification will be announced on 2021.12.20.
|
some smaller issues. The final specification will be announced on 2021.12.20.
|
||||||
Thanks for your patience! The WIP file format specification can be found in
|
Thanks for your patience! The WIP file format specification can be found in
|
||||||
@ -30,6 +28,22 @@ converts between png <> qoi
|
|||||||
a simple wrapper to benchmark stbi, libpng and qoi
|
a simple wrapper to benchmark stbi, libpng and qoi
|
||||||
|
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
The QOI file format allows for huge images with up to 18 exa-pixels. A streaming
|
||||||
|
en-/decoder can handle these with minimal RAM requirements, assuming there is
|
||||||
|
enough storage space.
|
||||||
|
|
||||||
|
This particular implementation of QOI however is limited to images with a
|
||||||
|
maximum size of 400 million pixels. It will safely refuse to en-/decode anything
|
||||||
|
larger than that. This is not a streaming en-/decoder. It loads the whole image
|
||||||
|
file into RAM before doing any work and is not extensively optimized for
|
||||||
|
performance (but it's still very fast).
|
||||||
|
|
||||||
|
If this is a limitation for your use case, please look into any of the other
|
||||||
|
implementations listed below.
|
||||||
|
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
- https://github.com/floooh/qoiview
|
- https://github.com/floooh/qoiview
|
||||||
|
16
qoi.h
16
qoi.h
@ -344,6 +344,12 @@ Implementation */
|
|||||||
#define QOI_HEADER_SIZE 14
|
#define QOI_HEADER_SIZE 14
|
||||||
#define QOI_PADDING 8
|
#define QOI_PADDING 8
|
||||||
|
|
||||||
|
/* 2GB is the max file size that this implementation can safely handle. We guard
|
||||||
|
against anything larger than that, assuming the worst case with 5 bytes per
|
||||||
|
pixel, rounded down to a nice clean value. 400 million pixels ought to be
|
||||||
|
enough for anybody. */
|
||||||
|
#define QOI_PIXELS_MAX ((unsigned int)400000000)
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct { unsigned char r, g, b, a; } rgba;
|
struct { unsigned char r, g, b, a; } rgba;
|
||||||
unsigned int v;
|
unsigned int v;
|
||||||
@ -376,7 +382,8 @@ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) {
|
|||||||
data == NULL || out_len == NULL || desc == NULL ||
|
data == NULL || out_len == NULL || desc == NULL ||
|
||||||
desc->width == 0 || desc->height == 0 ||
|
desc->width == 0 || desc->height == 0 ||
|
||||||
desc->channels < 3 || desc->channels > 4 ||
|
desc->channels < 3 || desc->channels > 4 ||
|
||||||
desc->colorspace > 2
|
desc->colorspace > 2 ||
|
||||||
|
desc->height >= QOI_PIXELS_MAX / desc->width
|
||||||
) {
|
) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -525,7 +532,8 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) {
|
|||||||
desc->width == 0 || desc->height == 0 ||
|
desc->width == 0 || desc->height == 0 ||
|
||||||
desc->channels < 3 || desc->channels > 4 ||
|
desc->channels < 3 || desc->channels > 4 ||
|
||||||
desc->colorspace > 2 ||
|
desc->colorspace > 2 ||
|
||||||
header_magic != QOI_MAGIC
|
header_magic != QOI_MAGIC ||
|
||||||
|
desc->height >= QOI_PIXELS_MAX / desc->width
|
||||||
) {
|
) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -636,6 +644,10 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels) {
|
|||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
size = ftell(f);
|
size = ftell(f);
|
||||||
|
if (size <= 0) {
|
||||||
|
fclose(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
data = QOI_MALLOC(size);
|
data = QOI_MALLOC(size);
|
||||||
|
Loading…
Reference in New Issue
Block a user