diff --git a/src/jpegcompress.c b/src/jpegcompress.c
index 6e8dc87..486814e 100644
@@ -1,7 +1,7 @@
#include "proto.h"
struct JPEG_encoded_value * generate_JPEG_luminance_data_stream (struct context * context, double (* restrict data)[64], size_t units,
- const uint8_t quantization[restrict static 64], size_t * restrict count) {
+ const uint8_t quantization[RESTRICT_STATIC 64], size_t * restrict count) {
*count = 0;
size_t allocated = 3 * units + 64;
struct JPEG_encoded_value * result = ctxmalloc(context, sizeof *result * allocated);
@@ -18,7 +18,7 @@ struct JPEG_encoded_value * generate_JPEG_luminance_data_stream (struct context
}
struct JPEG_encoded_value * generate_JPEG_chrominance_data_stream (struct context * context, double (* restrict blue)[64], double (* restrict red)[64],
- size_t units, const uint8_t quantization[restrict static 64], size_t * restrict count) {
+ size_t units, const uint8_t quantization[RESTRICT_STATIC 64], size_t * restrict count) {
*count = 0;
size_t allocated = 6 * units + 128;
struct JPEG_encoded_value * result = ctxmalloc(context, sizeof *result * allocated);
@@ -35,8 +35,8 @@ struct JPEG_encoded_value * generate_JPEG_chrominance_data_stream (struct contex
return ctxrealloc(context, result, *count * sizeof *result);
}
-double generate_JPEG_data_unit (struct JPEG_encoded_value * data, size_t * restrict count, const double unit[restrict static 64],
- const uint8_t quantization[restrict static 64], double predicted) {
+double generate_JPEG_data_unit (struct JPEG_encoded_value * data, size_t * restrict count, const double unit[RESTRICT_STATIC 64],
+ const uint8_t quantization[RESTRICT_STATIC 64], double predicted) {
int16_t output[64];
predicted = apply_JPEG_DCT(output, unit, quantization, predicted);
uint_fast8_t last = 0;
@@ -58,7 +58,7 @@ void encode_JPEG_value (struct JPEG_encoded_value * data, int16_t value, unsigne
}
size_t generate_JPEG_Huffman_table (struct context * context, const struct JPEG_encoded_value * data, size_t count, unsigned char * restrict output,
- unsigned char table[restrict static 0x100], unsigned char index) {
+ unsigned char table[RESTRICT_STATIC 0x100], unsigned char index) {
// returns the number of bytes spent encoding the table in the JPEG data (in output)
size_t counts[0x101] = {[0x100] = 1}; // use 0x100 as a dummy value to absorb the highest (invalid) code
unsigned char lengths[0x101];
@@ -87,7 +87,7 @@ size_t generate_JPEG_Huffman_table (struct context * context, const struct JPEG_
return outsize;
}
-void encode_JPEG_scan (struct context * context, const struct JPEG_encoded_value * data, size_t count, const unsigned char table[restrict static 0x200]) {
+void encode_JPEG_scan (struct context * context, const struct JPEG_encoded_value * data, size_t count, const unsigned char table[RESTRICT_STATIC 0x200]) {
unsigned short codes[0x200]; // no need to create a dummy entry for the highest (invalid) code here: it simply won't be generated
generate_Huffman_codes(codes, 0x100, table, false);
generate_Huffman_codes(codes + 0x100, 0x100, table + 0x100, false);
diff --git a/src/jpegdct.c b/src/jpegdct.c
index 57bbbb9..f74cc0c 100644
@@ -13,7 +13,7 @@
// half the square root of 2
#define HR2 0x0.b504f333f9de68p+0
-double apply_JPEG_DCT (int16_t output[restrict static 64], const double input[restrict static 64], const uint8_t quantization[restrict static 64], double prevDC) {
+double apply_JPEG_DCT (int16_t output[RESTRICT_STATIC 64], const double input[RESTRICT_STATIC 64], const uint8_t quantization[RESTRICT_STATIC 64], double prevDC) {
// coefficient(dst, src) = cos((2 * src + 1) * dst * pi / 16) / 2; this absorbs a leading factor of 1/4 (square rooted)
static const double coefficients[8][8] = {
{0.5, C1, C2, C3, C4, C5, C6, C7},
@@ -72,7 +72,7 @@ double apply_JPEG_DCT (int16_t output[restrict static 64], const double input[re
return prevDC + *output;
}
-void apply_JPEG_inverse_DCT (double output[restrict static 64], const int16_t input[restrict static 64], const uint16_t quantization[restrict static 64]) {
+void apply_JPEG_inverse_DCT (double output[RESTRICT_STATIC 64], const int16_t input[RESTRICT_STATIC 64], const uint16_t quantization[RESTRICT_STATIC 64]) {
// coefficient(dst, src) = 0.5 * (src ? cos((2 * dst + 1) * src * pi / 16) : 1 / sqrt(2)); this absorbs a leading factor of 1/4 (square rooted)
static const double coefficients[8][8] = {
{C4, C1, C2, C3, C4, C5, C6, C7},
diff --git a/src/jpegwrite.c b/src/jpegwrite.c
index 79980b2..63d46ff 100644
@@ -59,7 +59,7 @@ void generate_JPEG_data (struct context * context) {
byteoutput(context, 0xff, 0xd9); // EOI
}
-void calculate_JPEG_quantization_tables (struct context * context, uint8_t luminance_table[restrict static 64], uint8_t chrominance_table[restrict static 64]) {
+void calculate_JPEG_quantization_tables (struct context * context, uint8_t luminance_table[RESTRICT_STATIC 64], uint8_t chrominance_table[RESTRICT_STATIC 64]) {
// start with the standard's tables (reduced by 1, since that will be added back later)
static const uint8_t luminance_base[64] = { 15, 10, 11, 13, 11, 9, 15, 13, 12, 13, 17, 16, 15, 18, 23, 39, 25, 23, 21, 21, 23,
48, 34, 36, 28, 39, 57, 50, 60, 59, 56, 50, 55, 54, 63, 71, 91, 77, 63, 67, 86, 68,
diff --git a/src/pngcompress.c b/src/pngcompress.c
index 2781435..9ababaa 100644
@@ -255,8 +255,8 @@ unsigned char * emit_PNG_compressed_block (struct context * context, const struc
}
unsigned char * generate_PNG_Huffman_trees (struct context * context, uint32_t * restrict dataword, uint8_t * restrict bits, size_t * restrict size,
- const size_t codecounts[restrict static 0x120], const size_t distcounts[restrict static 0x20],
- unsigned char codelengths[restrict static 0x120], unsigned char distlengths[restrict static 0x20]) {
+ const size_t codecounts[RESTRICT_STATIC 0x120], const size_t distcounts[RESTRICT_STATIC 0x20],
+ unsigned char codelengths[RESTRICT_STATIC 0x120], unsigned char distlengths[RESTRICT_STATIC 0x20]) {
// this function will generate trees, discard them and only preserve the lengths; that way, the real (properly ordered) trees can be rebuilt later
// also outputs the tree length data to the output stream and returns it
generate_Huffman_tree(context, codecounts, codelengths, 0x120, 15);
diff --git a/src/pngdecompress.c b/src/pngdecompress.c
index f180209..4405892 100644
@@ -44,7 +44,7 @@ void * decompress_PNG_data (struct context * context, const unsigned char * comp
return decompressed;
}
-void extract_PNG_code_table (struct context * context, const unsigned char ** compressed, size_t * restrict size, unsigned char codesizes[restrict static 0x140],
+void extract_PNG_code_table (struct context * context, const unsigned char ** compressed, size_t * restrict size, unsigned char codesizes[RESTRICT_STATIC 0x140],
uint32_t * restrict dataword, uint8_t * restrict bits) {
uint_fast16_t header = shift_in_left(context, 14, dataword, bits, compressed, size);
unsigned literals = 0x101 + (header & 0x1f);
@@ -81,7 +81,7 @@ void extract_PNG_code_table (struct context * context, const unsigned char ** co
void decompress_PNG_block (struct context * context, const unsigned char ** compressed, unsigned char * restrict decompressed, size_t * restrict size,
size_t * restrict current, size_t expected, uint32_t * restrict dataword, uint8_t * restrict bits,
- const unsigned char codesizes[restrict static 0x140]) {
+ const unsigned char codesizes[RESTRICT_STATIC 0x140]) {
// a single list of codesizes for all codes: 0x00-0xff for literals, 0x100 for end of codes, 0x101-0x11d for lengths, 0x120-0x13d for distances
short * codetree = decode_PNG_Huffman_tree(context, codesizes, 0x120);
if (!codetree) throw(context, PLUM_ERR_INVALID_FILE_FORMAT);
diff --git a/src/proto.h b/src/proto.h
index 7d5d2c0..cfca95a 100644
@@ -7,6 +7,16 @@
#include <stdalign.h>
#include <setjmp.h>
+#ifdef _MSC_VER
+// MSVC 2022 is still not conformant to C17 despite claiming otherwise, so we need to provide `max_align_t`.
+// (...interestingly, that type *is* provided in C++ mode... ack.)
+// According to https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/malloc?view=msvc-170,
+// `malloc` provides a 16-byte alignment.
+// `__m128` is 16-byte-aligned. It'll do.
+#include <xmmintrin.h>
+typedef __m128 max_align_t;
+#endif
+
#include "defs.h"
#include "../header/libplum.h"
#include "struct.h"
@@ -14,6 +24,13 @@
#include "data.h"
#include "multibyte.h"
+// MSVC 2022 is *still* not C17 conformant.
+#ifndef _MSC_VER
+#define RESTRICT_STATIC restrict static
+#else
+#define RESTRICT_STATIC
+#endif
+
// allocator.c
internal void * attach_allocator_node(struct allocator_node **, struct allocator_node *);
internal void * allocate(struct allocator_node **, size_t);
@@ -153,20 +170,20 @@ internal void JPEG_transfer_CMYK(uint64_t * restrict, size_t, unsigned, const do
internal void JPEG_transfer_CKMY(uint64_t * restrict, size_t, unsigned, const double **);
// jpegcompress.c
-internal struct JPEG_encoded_value * generate_JPEG_luminance_data_stream(struct context *, double (* restrict)[64], size_t, const uint8_t [restrict static 64],
+internal struct JPEG_encoded_value * generate_JPEG_luminance_data_stream(struct context *, double (* restrict)[64], size_t, const uint8_t [RESTRICT_STATIC 64],
size_t * restrict);
internal struct JPEG_encoded_value * generate_JPEG_chrominance_data_stream(struct context *, double (* restrict)[64], double (* restrict)[64], size_t,
- const uint8_t [restrict static 64], size_t * restrict);
-internal double generate_JPEG_data_unit(struct JPEG_encoded_value *, size_t * restrict, const double [restrict static 64], const uint8_t [restrict static 64],
+ const uint8_t [RESTRICT_STATIC 64], size_t * restrict);
+internal double generate_JPEG_data_unit(struct JPEG_encoded_value *, size_t * restrict, const double [RESTRICT_STATIC 64], const uint8_t [RESTRICT_STATIC 64],
double);
internal void encode_JPEG_value(struct JPEG_encoded_value *, int16_t, unsigned, unsigned char);
internal size_t generate_JPEG_Huffman_table(struct context *, const struct JPEG_encoded_value *, size_t, unsigned char * restrict,
- unsigned char [restrict static 0x100], unsigned char);
-internal void encode_JPEG_scan(struct context *, const struct JPEG_encoded_value *, size_t, const unsigned char [restrict static 0x200]);
+ unsigned char [RESTRICT_STATIC 0x100], unsigned char);
+internal void encode_JPEG_scan(struct context *, const struct JPEG_encoded_value *, size_t, const unsigned char [RESTRICT_STATIC 0x200]);
// jpegdct.c
-internal double apply_JPEG_DCT(int16_t [restrict static 64], const double [restrict static 64], const uint8_t [restrict static 64], double);
-internal void apply_JPEG_inverse_DCT(double [restrict static 64], const int16_t [restrict static 64], const uint16_t [restrict static 64]);
+internal double apply_JPEG_DCT(int16_t [RESTRICT_STATIC 64], const double [RESTRICT_STATIC 64], const uint8_t [RESTRICT_STATIC 64], double);
+internal void apply_JPEG_inverse_DCT(double [RESTRICT_STATIC 64], const int16_t [RESTRICT_STATIC 64], const uint16_t [RESTRICT_STATIC 64]);
// jpegdecompress.c
internal void initialize_JPEG_decompressor_state(struct context *, struct JPEG_decompressor_state * restrict, const struct JPEG_component_info *,
@@ -221,7 +238,7 @@ internal void load_default_JPEG_Huffman_tables(struct context *, struct JPEG_dec
// jpegwrite.c
internal void generate_JPEG_data(struct context *);
-internal void calculate_JPEG_quantization_tables(struct context *, uint8_t [restrict static 64], uint8_t [restrict static 64]);
+internal void calculate_JPEG_quantization_tables(struct context *, uint8_t [RESTRICT_STATIC 64], uint8_t [RESTRICT_STATIC 64]);
internal void convert_JPEG_components_to_YCbCr(struct context *, double (* restrict)[64], double (* restrict)[64], double (* restrict)[64]);
internal void convert_JPEG_colors_to_YCbCr(const void * restrict, size_t, unsigned char, double * restrict, double * restrict, double * restrict,
uint64_t * restrict);
@@ -267,15 +284,15 @@ internal void emit_PNG_code(struct context *, struct compressed_PNG_code **, siz
internal unsigned char * emit_PNG_compressed_block(struct context *, const struct compressed_PNG_code * restrict, size_t, bool, size_t * restrict,
uint32_t * restrict, uint8_t * restrict);
internal unsigned char * generate_PNG_Huffman_trees(struct context *, uint32_t * restrict, uint8_t * restrict, size_t * restrict,
- const size_t [restrict static 0x120], const size_t [restrict static 0x20],
- unsigned char [restrict static 0x120], unsigned char [restrict static 0x20]);
+ const size_t [RESTRICT_STATIC 0x120], const size_t [RESTRICT_STATIC 0x20],
+ unsigned char [RESTRICT_STATIC 0x120], unsigned char [RESTRICT_STATIC 0x20]);
// pngdecompress.c
internal void * decompress_PNG_data(struct context *, const unsigned char *, size_t, size_t);
-internal void extract_PNG_code_table(struct context *, const unsigned char **, size_t * restrict, unsigned char [restrict static 0x140], uint32_t * restrict,
+internal void extract_PNG_code_table(struct context *, const unsigned char **, size_t * restrict, unsigned char [RESTRICT_STATIC 0x140], uint32_t * restrict,
uint8_t * restrict);
internal void decompress_PNG_block(struct context *, const unsigned char **, unsigned char * restrict, size_t * restrict, size_t * restrict, size_t,
- uint32_t * restrict, uint8_t * restrict, const unsigned char [restrict static 0x140]);
+ uint32_t * restrict, uint8_t * restrict, const unsigned char [RESTRICT_STATIC 0x140]);
internal short * decode_PNG_Huffman_tree(struct context *, const unsigned char *, unsigned);
internal uint16_t next_PNG_Huffman_code(struct context *, const short * restrict, const unsigned char **, size_t * restrict, uint32_t * restrict,
uint8_t * restrict);