Style: Remove trailing whitespaces
This commit is contained in:
parent
c04a975e00
commit
b060b961e8
94
qoi.h
94
qoi.h
@ -28,8 +28,8 @@ SOFTWARE.
|
|||||||
|
|
||||||
-- About
|
-- About
|
||||||
|
|
||||||
QOI encodes and decodes images in a lossless format. Compared to stb_image and
|
QOI encodes and decodes images in a lossless format. Compared to stb_image and
|
||||||
stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and
|
stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and
|
||||||
20% better compression.
|
20% better compression.
|
||||||
|
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and
|
|||||||
// the input pixel data.
|
// the input pixel data.
|
||||||
qoi_write("image_new.qoi", rgba_pixels, &(qoi_desc){
|
qoi_write("image_new.qoi", rgba_pixels, &(qoi_desc){
|
||||||
.width = 1920,
|
.width = 1920,
|
||||||
.height = 1080,
|
.height = 1080,
|
||||||
.channels = 4,
|
.channels = 4,
|
||||||
.colorspace = QOI_SRGB
|
.colorspace = QOI_SRGB
|
||||||
});
|
});
|
||||||
@ -74,7 +74,7 @@ QOI_NO_STDIO before including this library.
|
|||||||
This library uses malloc() and free(). To supply your own malloc implementation
|
This library uses malloc() and free(). To supply your own malloc implementation
|
||||||
you can define QOI_MALLOC and QOI_FREE before including this library.
|
you can define QOI_MALLOC and QOI_FREE before including this library.
|
||||||
|
|
||||||
This library uses memset() to zero-initialize the index. To supply your own
|
This library uses memset() to zero-initialize the index. To supply your own
|
||||||
implementation you can define QOI_ZEROARR before including this library.
|
implementation you can define QOI_ZEROARR before including this library.
|
||||||
|
|
||||||
|
|
||||||
@ -91,8 +91,8 @@ struct qoi_header_t {
|
|||||||
uint8_t colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear
|
uint8_t colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear
|
||||||
};
|
};
|
||||||
|
|
||||||
Images are encoded row by row, left to right, top to bottom. The decoder and
|
Images are encoded row by row, left to right, top to bottom. The decoder and
|
||||||
encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value. An
|
encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value. An
|
||||||
image is complete when all pixels specified by width * height have been covered.
|
image is complete when all pixels specified by width * height have been covered.
|
||||||
|
|
||||||
Pixels are encoded as
|
Pixels are encoded as
|
||||||
@ -101,20 +101,20 @@ Pixels are encoded as
|
|||||||
- a difference to the previous pixel value in r,g,b
|
- a difference to the previous pixel value in r,g,b
|
||||||
- full r,g,b or r,g,b,a values
|
- full r,g,b or r,g,b,a values
|
||||||
|
|
||||||
The color channels are assumed to not be premultiplied with the alpha channel
|
The color channels are assumed to not be premultiplied with the alpha channel
|
||||||
("un-premultiplied alpha").
|
("un-premultiplied alpha").
|
||||||
|
|
||||||
A running array[64] (zero-initialized) of previously seen pixel values is
|
A running array[64] (zero-initialized) of previously seen pixel values is
|
||||||
maintained by the encoder and decoder. Each pixel that is seen by the encoder
|
maintained by the encoder and decoder. Each pixel that is seen by the encoder
|
||||||
and decoder is put into this array at the position formed by a hash function of
|
and decoder is put into this array at the position formed by a hash function of
|
||||||
the color value. In the encoder, if the pixel value at the index matches the
|
the color value. In the encoder, if the pixel value at the index matches the
|
||||||
current pixel, this index position is written to the stream as QOI_OP_INDEX.
|
current pixel, this index position is written to the stream as QOI_OP_INDEX.
|
||||||
The hash function for the index is:
|
The hash function for the index is:
|
||||||
|
|
||||||
index_position = (r * 3 + g * 5 + b * 7 + a * 11) % 64
|
index_position = (r * 3 + g * 5 + b * 7 + a * 11) % 64
|
||||||
|
|
||||||
Each chunk starts with a 2- or 8-bit tag, followed by a number of data bits. The
|
Each chunk starts with a 2- or 8-bit tag, followed by a number of data bits. The
|
||||||
bit length of chunks is divisible by 8 - i.e. all chunks are byte aligned. All
|
bit length of chunks is divisible by 8 - i.e. all chunks are byte aligned. All
|
||||||
values encoded in these data bits have the most significant bit on the left.
|
values encoded in these data bits have the most significant bit on the left.
|
||||||
|
|
||||||
The 8-bit tags have precedence over the 2-bit tags. A decoder must check for the
|
The 8-bit tags have precedence over the 2-bit tags. A decoder must check for the
|
||||||
@ -136,10 +136,10 @@ The possible chunks are:
|
|||||||
6-bit index into the color index array: 0..63
|
6-bit index into the color index array: 0..63
|
||||||
|
|
||||||
A valid encoder must not issue 7 or more consecutive QOI_OP_INDEX chunks to the
|
A valid encoder must not issue 7 or more consecutive QOI_OP_INDEX chunks to the
|
||||||
index 0, to avoid confusion with the 8 byte end marker.
|
index 0, to avoid confusion with the 8 byte end marker.
|
||||||
|
|
||||||
|
|
||||||
.- QOI_OP_DIFF -----------.
|
.- QOI_OP_DIFF -----------.
|
||||||
| Byte[0] |
|
| Byte[0] |
|
||||||
| 7 6 5 4 3 2 1 0 |
|
| 7 6 5 4 3 2 1 0 |
|
||||||
|-------+-----+-----+-----|
|
|-------+-----+-----+-----|
|
||||||
@ -150,16 +150,16 @@ index 0, to avoid confusion with the 8 byte end marker.
|
|||||||
2-bit green channel difference from the previous pixel between -2..1
|
2-bit green channel difference from the previous pixel between -2..1
|
||||||
2-bit blue channel difference from the previous pixel between -2..1
|
2-bit blue channel difference from the previous pixel between -2..1
|
||||||
|
|
||||||
The difference to the current channel values are using a wraparound operation,
|
The difference to the current channel values are using a wraparound operation,
|
||||||
so "1 - 2" will result in 255, while "255 + 1" will result in 0.
|
so "1 - 2" will result in 255, while "255 + 1" will result in 0.
|
||||||
|
|
||||||
Values are stored as unsigned integers with a bias of 2. E.g. -2 is stored as
|
Values are stored as unsigned integers with a bias of 2. E.g. -2 is stored as
|
||||||
0 (b00). 1 is stored as 3 (b11).
|
0 (b00). 1 is stored as 3 (b11).
|
||||||
|
|
||||||
The alpha value remains unchanged from the previous pixel.
|
The alpha value remains unchanged from the previous pixel.
|
||||||
|
|
||||||
|
|
||||||
.- QOI_OP_LUMA -------------------------------------.
|
.- QOI_OP_LUMA -------------------------------------.
|
||||||
| Byte[0] | Byte[1] |
|
| Byte[0] | Byte[1] |
|
||||||
| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |
|
| 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 |
|
||||||
|-------+-----------------+-------------+-----------|
|
|-------+-----------------+-------------+-----------|
|
||||||
@ -170,16 +170,16 @@ The alpha value remains unchanged from the previous pixel.
|
|||||||
4-bit red channel difference minus green channel difference -8..7
|
4-bit red channel difference minus green channel difference -8..7
|
||||||
4-bit blue channel difference minus green channel difference -8..7
|
4-bit blue channel difference minus green channel difference -8..7
|
||||||
|
|
||||||
The green channel is used to indicate the general direction of change and is
|
The green channel is used to indicate the general direction of change and is
|
||||||
encoded in 6 bits. The red and blue channels (dr and db) base their diffs off
|
encoded in 6 bits. The red and blue channels (dr and db) base their diffs off
|
||||||
of the green channel difference and are encoded in 4 bits. I.e.:
|
of the green channel difference and are encoded in 4 bits. I.e.:
|
||||||
dr_dg = (last_px.r - cur_px.r) - (last_px.g - cur_px.g)
|
dr_dg = (last_px.r - cur_px.r) - (last_px.g - cur_px.g)
|
||||||
db_dg = (last_px.b - cur_px.b) - (last_px.g - cur_px.g)
|
db_dg = (last_px.b - cur_px.b) - (last_px.g - cur_px.g)
|
||||||
|
|
||||||
The difference to the current channel values are using a wraparound operation,
|
The difference to the current channel values are using a wraparound operation,
|
||||||
so "10 - 13" will result in 253, while "250 + 7" will result in 1.
|
so "10 - 13" will result in 253, while "250 + 7" will result in 1.
|
||||||
|
|
||||||
Values are stored as unsigned integers with a bias of 32 for the green channel
|
Values are stored as unsigned integers with a bias of 32 for the green channel
|
||||||
and a bias of 8 for the red and blue channel.
|
and a bias of 8 for the red and blue channel.
|
||||||
|
|
||||||
The alpha value remains unchanged from the previous pixel.
|
The alpha value remains unchanged from the previous pixel.
|
||||||
@ -194,8 +194,8 @@ The alpha value remains unchanged from the previous pixel.
|
|||||||
2-bit tag b11
|
2-bit tag b11
|
||||||
6-bit run-length repeating the previous pixel: 1..62
|
6-bit run-length repeating the previous pixel: 1..62
|
||||||
|
|
||||||
The run-length is stored with a bias of -1. Note that the run-lengths 63 and 64
|
The run-length is stored with a bias of -1. Note that the run-lengths 63 and 64
|
||||||
(b111110 and b111111) are illegal as they are occupied by the QOI_OP_RGB and
|
(b111110 and b111111) are illegal as they are occupied by the QOI_OP_RGB and
|
||||||
QOI_OP_RGBA tags.
|
QOI_OP_RGBA tags.
|
||||||
|
|
||||||
|
|
||||||
@ -238,15 +238,15 @@ Header - Public functions */
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* A pointer to a qoi_desc struct has to be supplied to all of qoi's functions.
|
/* A pointer to a qoi_desc struct has to be supplied to all of qoi's functions.
|
||||||
It describes either the input format (for qoi_write and qoi_encode), or is
|
It describes either the input format (for qoi_write and qoi_encode), or is
|
||||||
filled with the description read from the file header (for qoi_read and
|
filled with the description read from the file header (for qoi_read and
|
||||||
qoi_decode).
|
qoi_decode).
|
||||||
|
|
||||||
The colorspace in this qoi_desc is an enum where
|
The colorspace in this qoi_desc is an enum where
|
||||||
0 = sRGB, i.e. gamma scaled RGB channels and a linear alpha channel
|
0 = sRGB, i.e. gamma scaled RGB channels and a linear alpha channel
|
||||||
1 = all channels are linear
|
1 = all channels are linear
|
||||||
You may use the constants QOI_SRGB or QOI_LINEAR. The colorspace is purely
|
You may use the constants QOI_SRGB or QOI_LINEAR. The colorspace is purely
|
||||||
informative. It will be saved to the file header, but does not affect
|
informative. It will be saved to the file header, but does not affect
|
||||||
en-/decoding in any way. */
|
en-/decoding in any way. */
|
||||||
|
|
||||||
@ -262,11 +262,11 @@ typedef struct {
|
|||||||
|
|
||||||
#ifndef QOI_NO_STDIO
|
#ifndef QOI_NO_STDIO
|
||||||
|
|
||||||
/* Encode raw RGB or RGBA pixels into a QOI image and write it to the file
|
/* Encode raw RGB or RGBA pixels into a QOI image and write it to the file
|
||||||
system. The qoi_desc struct must be filled with the image width, height,
|
system. The qoi_desc struct must be filled with the image width, height,
|
||||||
number of channels (3 = RGB, 4 = RGBA) and the colorspace.
|
number of channels (3 = RGB, 4 = RGBA) and the colorspace.
|
||||||
|
|
||||||
The function returns 0 on failure (invalid parameters, or fopen or malloc
|
The function returns 0 on failure (invalid parameters, or fopen or malloc
|
||||||
failed) or the number of bytes written on success. */
|
failed) or the number of bytes written on success. */
|
||||||
|
|
||||||
int qoi_write(const char *filename, const void *data, const qoi_desc *desc);
|
int qoi_write(const char *filename, const void *data, const qoi_desc *desc);
|
||||||
@ -277,7 +277,7 @@ number of channels from the file header is used. If channels is 3 or 4 the
|
|||||||
output format will be forced into this number of channels.
|
output format will be forced into this number of channels.
|
||||||
|
|
||||||
The function either returns NULL on failure (invalid data, or malloc or fopen
|
The function either returns NULL on failure (invalid data, or malloc or fopen
|
||||||
failed) or a pointer to the decoded pixels. On success, the qoi_desc struct
|
failed) or a pointer to the decoded pixels. On success, the qoi_desc struct
|
||||||
will be filled with the description from the file header.
|
will be filled with the description from the file header.
|
||||||
|
|
||||||
The returned pixel data should be free()d after use. */
|
The returned pixel data should be free()d after use. */
|
||||||
@ -289,8 +289,8 @@ void *qoi_read(const char *filename, qoi_desc *desc, int channels);
|
|||||||
|
|
||||||
/* Encode raw RGB or RGBA pixels into a QOI image in memory.
|
/* Encode raw RGB or RGBA pixels into a QOI image in memory.
|
||||||
|
|
||||||
The function either returns NULL on failure (invalid parameters or malloc
|
The function either returns NULL on failure (invalid parameters or malloc
|
||||||
failed) or a pointer to the encoded data on success. On success the out_len
|
failed) or a pointer to the encoded data on success. On success the out_len
|
||||||
is set to the size in bytes of the encoded data.
|
is set to the size in bytes of the encoded data.
|
||||||
|
|
||||||
The returned qoi data should be free()d after use. */
|
The returned qoi data should be free()d after use. */
|
||||||
@ -300,8 +300,8 @@ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len);
|
|||||||
|
|
||||||
/* Decode a QOI image from memory.
|
/* Decode a QOI image from memory.
|
||||||
|
|
||||||
The function either returns NULL on failure (invalid parameters or malloc
|
The function either returns NULL on failure (invalid parameters or malloc
|
||||||
failed) or a pointer to the decoded pixels. On success, the qoi_desc struct
|
failed) or a pointer to the decoded pixels. On success, the qoi_desc struct
|
||||||
is filled with the description from the file header.
|
is filled with the description from the file header.
|
||||||
|
|
||||||
The returned pixel data should be free()d after use. */
|
The returned pixel data should be free()d after use. */
|
||||||
@ -346,8 +346,8 @@ Implementation */
|
|||||||
#define QOI_HEADER_SIZE 14
|
#define QOI_HEADER_SIZE 14
|
||||||
|
|
||||||
/* 2GB is the max file size that this implementation can safely handle. We guard
|
/* 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
|
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
|
pixel, rounded down to a nice clean value. 400 million pixels ought to be
|
||||||
enough for anybody. */
|
enough for anybody. */
|
||||||
#define QOI_PIXELS_MAX ((unsigned int)400000000)
|
#define QOI_PIXELS_MAX ((unsigned int)400000000)
|
||||||
|
|
||||||
@ -391,8 +391,8 @@ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_size =
|
max_size =
|
||||||
desc->width * desc->height * (desc->channels + 1) +
|
desc->width * desc->height * (desc->channels + 1) +
|
||||||
QOI_HEADER_SIZE + sizeof(qoi_padding);
|
QOI_HEADER_SIZE + sizeof(qoi_padding);
|
||||||
|
|
||||||
p = 0;
|
p = 0;
|
||||||
@ -418,7 +418,7 @@ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) {
|
|||||||
px_prev.rgba.b = 0;
|
px_prev.rgba.b = 0;
|
||||||
px_prev.rgba.a = 255;
|
px_prev.rgba.a = 255;
|
||||||
px = px_prev;
|
px = px_prev;
|
||||||
|
|
||||||
px_len = desc->width * desc->height * desc->channels;
|
px_len = desc->width * desc->height * desc->channels;
|
||||||
px_end = px_len - desc->channels;
|
px_end = px_len - desc->channels;
|
||||||
channels = desc->channels;
|
channels = desc->channels;
|
||||||
@ -466,14 +466,14 @@ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
vr > -3 && vr < 2 &&
|
vr > -3 && vr < 2 &&
|
||||||
vg > -3 && vg < 2 &&
|
vg > -3 && vg < 2 &&
|
||||||
vb > -3 && vb < 2
|
vb > -3 && vb < 2
|
||||||
) {
|
) {
|
||||||
bytes[p++] = QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2);
|
bytes[p++] = QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2);
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
vg_r > -9 && vg_r < 8 &&
|
vg_r > -9 && vg_r < 8 &&
|
||||||
vg > -33 && vg < 32 &&
|
vg > -33 && vg < 32 &&
|
||||||
vg_b > -9 && vg_b < 8
|
vg_b > -9 && vg_b < 8
|
||||||
) {
|
) {
|
||||||
bytes[p++] = QOI_OP_LUMA | (vg + 32);
|
bytes[p++] = QOI_OP_LUMA | (vg + 32);
|
||||||
@ -532,7 +532,7 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) {
|
|||||||
desc->colorspace = bytes[p++];
|
desc->colorspace = bytes[p++];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
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 > 1 ||
|
desc->colorspace > 1 ||
|
||||||
header_magic != QOI_MAGIC ||
|
header_magic != QOI_MAGIC ||
|
||||||
@ -598,7 +598,7 @@ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) {
|
|||||||
index[QOI_COLOR_HASH(px) % 64] = px;
|
index[QOI_COLOR_HASH(px) % 64] = px;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channels == 4) {
|
if (channels == 4) {
|
||||||
*(qoi_rgba_t*)(pixels + px_pos) = px;
|
*(qoi_rgba_t*)(pixels + px_pos) = px;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -627,11 +627,11 @@ int qoi_write(const char *filename, const void *data, const qoi_desc *desc) {
|
|||||||
if (!encoded) {
|
if (!encoded) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(encoded, 1, size, f);
|
fwrite(encoded, 1, size, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
QOI_FREE(encoded);
|
QOI_FREE(encoded);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user