Skip to content

Commit

Permalink
Miscellaneous non-QOI refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Rangi42 committed Nov 29, 2023
1 parent a8bcef2 commit 60b51a0
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 54 deletions.
12 changes: 6 additions & 6 deletions src/bmpwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,22 +333,22 @@ void generate_BMP_RGB_data (struct context * context, unsigned char * offset_poi
if ((context -> source -> color_format & PLUM_COLOR_MASK) == PLUM_COLOR_32)
data = context -> source -> data;
else {
data = ctxmalloc(context, sizeof *data * context -> source -> width * context -> source -> height);
plum_convert_colors(data, context -> source -> data, (size_t) context -> source -> width * context -> source -> height,
PLUM_COLOR_32, context -> source -> color_format);
size_t size = (size_t) context -> source -> width * context -> source -> height;
data = ctxmalloc(context, sizeof *data * size);
plum_convert_colors(data, context -> source -> data, size, PLUM_COLOR_32, context -> source -> color_format);
}
size_t rowsize = (size_t) context -> source -> width * 3, padding = 0;
if (rowsize & 3) {
padding = 4 - (rowsize & 3);
rowsize += padding;
}
unsigned char * out = append_output_node(context, rowsize * context -> source -> height);
unsigned char * output = append_output_node(context, rowsize * context -> source -> height);
uint_fast32_t row = context -> source -> height - 1;
do {
size_t pos = (size_t) row * context -> source -> width;
for (uint_fast32_t remaining = context -> source -> width; remaining; pos ++, remaining --)
out += byteappend(out, data[pos] >> 16, data[pos] >> 8, data[pos]);
for (uint_fast32_t p = 0; p < padding; p ++) *(out ++) = 0;
output += byteappend(output, data[pos] >> 16, data[pos] >> 8, data[pos]);
for (uint_fast32_t p = 0; p < padding; p ++) *(output ++) = 0;
} while (row --);
if (data != context -> source -> data) ctxfree(context, data);
}
67 changes: 26 additions & 41 deletions src/framebounds.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ struct plum_rectangle * get_frame_boundaries (struct context * context, bool anc

void adjust_frame_boundaries (const struct plum_image * image, struct plum_rectangle * restrict boundaries) {
uint64_t empty_color = get_empty_color(image);
#define checkframe(type) do \
for (uint_fast32_t frame = 0; frame < image -> frames; frame ++) { \
for (size_t remaining = (size_t) boundaries[frame].top * image -> width; remaining; remaining --) \
if (notempty(type)) goto done ## type; \
if (boundaries[frame].left || boundaries[frame].width != image -> width) \
for (uint_fast32_t row = 0; row < boundaries[frame].height; row ++) { \
for (uint_fast32_t col = 0; col < boundaries[frame].left; col ++) if (notempty(type)) goto done ## type; \
index += boundaries[frame].width; \
for (uint_fast32_t col = boundaries[frame].left + boundaries[frame].width; col < image -> width; col ++) \
if (notempty(type)) goto done ## type; \
} \
else \
index += (size_t) boundaries[frame].height * image -> width; \
for (size_t remaining = (size_t) (image -> height - boundaries[frame].top - boundaries[frame].height) * image -> width; remaining; remaining --) \
if (notempty(type)) goto done ## type; \
continue; \
done ## type: \
boundaries[frame] = (struct plum_rectangle) {.left = 0, .top = 0, .width = image -> width, .height = image -> height}; \
} \
while (false)
if (image -> palette) {
bool empty[256];
switch (image -> color_format & PLUM_COLOR_MASK) {
Expand All @@ -34,55 +54,20 @@ void adjust_frame_boundaries (const struct plum_image * image, struct plum_recta
for (size_t p = 0; p <= image -> max_palette_index; p ++) empty[p] = image -> palette32[p] == empty_color;
}
size_t index = 0;
for (uint_fast32_t frame = 0; frame < image -> frames; frame ++) {
bool adjust = true;
for (size_t remaining = (size_t) boundaries[frame].top * image -> width; remaining; remaining --)
if (!empty[image -> data8[index ++]]) goto paldone;
if (boundaries[frame].left || boundaries[frame].width != image -> width)
for (uint_fast32_t row = 0; row < boundaries[frame].height; row ++) {
for (uint_fast32_t col = 0; col < boundaries[frame].left; col ++) if (!empty[image -> data8[index ++]]) goto paldone;
index += boundaries[frame].width;
for (uint_fast32_t col = boundaries[frame].left + boundaries[frame].width; col < image -> width; col ++)
if (!empty[image -> data8[index ++]]) goto paldone;
}
else
index += (size_t) boundaries[frame].height * image -> width;
for (size_t remaining = (size_t) (image -> height - boundaries[frame].top - boundaries[frame].height) * image -> width; remaining; remaining --)
if (!empty[image -> data8[index ++]]) goto paldone;
adjust = false;
paldone:
if (adjust) boundaries[frame] = (struct plum_rectangle) {.left = 0, .top = 0, .width = image -> width, .height = image -> height};
}
#define notempty(...) (!empty[image -> data8[index ++]])
checkframe(pal);
} else {
size_t index = 0;
#define checkframe(bits) do \
for (uint_fast32_t frame = 0; frame < image -> frames; frame ++) { \
bool adjust = true; \
for (size_t remaining = (size_t) boundaries[frame].top * image -> width; remaining; remaining --) \
if (image -> data ## bits[index ++] != empty_color) goto done ## bits; \
if (boundaries[frame].left || boundaries[frame].width != image -> width) \
for (uint_fast32_t row = 0; row < boundaries[frame].height; row ++) { \
for (uint_fast32_t col = 0; col < boundaries[frame].left; col ++) if (image -> data ## bits[index ++] != empty_color) goto done ## bits; \
index += boundaries[frame].width; \
for (uint_fast32_t col = boundaries[frame].left + boundaries[frame].width; col < image -> width; col ++) \
if (image -> data ## bits[index ++] != empty_color) goto done ## bits; \
} \
else \
index += (size_t) boundaries[frame].height * image -> width; \
for (size_t remaining = (size_t) (image -> height - boundaries[frame].top - boundaries[frame].height) * image -> width; remaining; remaining --) \
if (image -> data ## bits[index ++] != empty_color) goto done ## bits; \
adjust = false; \
done ## bits: \
if (adjust) boundaries[frame] = (struct plum_rectangle) {.left = 0, .top = 0, .width = image -> width, .height = image -> height}; \
} \
while (false)
#undef notempty
#define notempty(bits) (image -> data ## bits[index ++] != empty_color)
switch (image -> color_format & PLUM_COLOR_MASK) {
case PLUM_COLOR_16: checkframe(16); break;
case PLUM_COLOR_64: checkframe(64); break;
default: checkframe(32);
}
#undef checkframe
}
#undef notempty
#undef checkframe
}

bool image_rectangles_have_transparency (const struct plum_image * image, const struct plum_rectangle * rectangles) {
Expand Down
3 changes: 1 addition & 2 deletions src/gifwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ void generate_GIF_data (struct context * context) {
if ((uint8_t) (depth >> 8) > overall) overall = depth >> 8;
if ((uint8_t) (depth >> 16) > overall) overall = depth >> 16;
if (overall > 8) overall = 8;
header[4] = (overall - 1) << 4;
header[5] = header[6] = 0;
bytewrite(header + 4, (overall - 1) << 4, 0, 0);
if (context -> source -> palette)
generate_GIF_data_with_palette(context, header);
else
Expand Down
2 changes: 1 addition & 1 deletion src/inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static inline uint16_t bitextend16 (uint16_t value, unsigned width) {
static inline void * append_output_node (struct context * context, size_t size) {
struct data_node * node = ctxmalloc(context, sizeof *node + size);
*node = (struct data_node) {.size = size, .previous = context -> output, .next = NULL};
if (context -> output) context -> output -> next = node;
if (node -> previous) node -> previous -> next = node;
context -> output = node;
return node -> data;
}
Expand Down
2 changes: 1 addition & 1 deletion src/pngcompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ size_t compute_uncompressed_PNG_block_size (const unsigned char * restrict data,
if (length) {
score += length - 1;
if (score >= 16) break;
} else if (score > 0)
} else if (score)
score --;
append_PNG_reference(data, current_offset, references);
}
Expand Down
4 changes: 1 addition & 3 deletions src/pngwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,7 @@ void append_PNG_header_chunks (struct context * context, unsigned type, uint32_t
unsigned char header[13];
write_be32_unaligned(header, context -> image -> width);
write_be32_unaligned(header + 4, context -> image -> height);
header[8] = (type < 4) ? 1 << type : (8 << (type >= 6));
header[9] = (type >= 4) ? 2 + 4 * (type & 1) : 3;
bytewrite(header + 10, 0, 0, 0);
bytewrite(header + 8, (type < 4) ? 1 << type : (8 << (type >= 6)), (type >= 4) ? 2 + 4 * (type & 1) : 3, 0, 0, 0);
output_PNG_chunk(context, 0x49484452u, sizeof header, header); // IHDR
unsigned char depthdata[4];
write_le32_unaligned(depthdata, depth); // this will write each byte of depth in the expected position
Expand Down

0 comments on commit 60b51a0

Please sign in to comment.