+#include "imext.h"
#include "msicon.h"
#include <string.h>
#include <stdlib.h>
static int
read_palette(ico_reader_t *file, ico_image_t *image, int *error);
static int
+read_24bit_data(ico_reader_t *file, ico_image_t *image, int *error);
+static int
read_32bit_data(ico_reader_t *file, ico_image_t *image, int *error);
static int
read_8bit_data(ico_reader_t *file, ico_image_t *image, int *error);
image->hotspot_y = hotspot_y;
}
- image->width = width;
- image->height = height;
+ /* a width or height of zero here indicates a width/height of 256 */
+ image->width = width ? width : 256;
+ image->height = height ? height : 256;
image->offset = image_offset;
image->size = bytes_in_res;
}
return NULL;
}
- if (bit_count != 1 && bit_count != 4 && bit_count != 8 && bit_count != 32) {
+ if (bit_count != 1 && bit_count != 4 && bit_count != 8
+ && bit_count != 24 && bit_count != 32) {
*error = ICOERR_Unknown_Bits;
return 0;
}
return NULL;
}
}
+ else if (bit_count == 24) {
+ result->palette_size = 0;
+
+ result->image_data = malloc(result->width * result->height * sizeof(ico_color_t));
+ if (!result->image_data) {
+ free(result);
+ *error = ICOERR_Out_Of_Memory;
+ return NULL;
+ }
+ if (!read_24bit_data(file, result, error)) {
+ free(result->image_data);
+ free(result);
+ return NULL;
+ }
+ }
else {
int read_result;
ico_image_t const *image = images + i;
int bits, colors;
int size = ico_image_size(image, &bits, &colors);
+ int width_byte = image->width == 256 ? 0 : image->width;
+ int height_byte = image->height == 256 ? 0 : image->height;
if (type == ICON_ICON) {
- if (!write_packed(ig, "bbbbwwdd", image->width, image->height,
+ if (!write_packed(ig, "bbbbwwdd", width_byte, height_byte,
colors, 0, 1, bits, (unsigned long)size,
(unsigned long)current_offset)) {
*error = ICOERR_Write_Failure;
else if (hotspot_y >= image->height)
hotspot_y = image->height - 1;
- if (!write_packed(ig, "bbbbwwdd", image->width, image->height,
+ if (!write_packed(ig, "bbbbwwdd", width_byte, height_byte,
colors, 0, hotspot_x, hotspot_y, (unsigned long)size,
(unsigned long)current_offset)) {
*error = ICOERR_Write_Failure;
return 1;
}
+/*
+=item read_24bit_data
+
+Reads 24 bit image data.
+
+=cut
+*/
+
+static
+int
+read_24bit_data(ico_reader_t *file, ico_image_t *image, int *error) {
+ int line_bytes = image->width * 3;
+ unsigned char *buffer;
+ int y;
+ int x;
+ unsigned char *inp;
+ ico_color_t *outp;
+
+ line_bytes = (line_bytes + 3) / 4 * 4;
+
+ buffer = malloc(line_bytes);
+
+ if (!buffer) {
+ *error = ICOERR_Out_Of_Memory;
+ return 0;
+ }
+
+ for (y = image->height - 1; y >= 0; --y) {
+ if (i_io_read(file->ig, buffer, line_bytes) != line_bytes) {
+ free(buffer);
+ *error = ICOERR_Short_File;
+ return 0;
+ }
+ outp = image->image_data;
+ outp += y * image->width;
+ inp = buffer;
+ for (x = 0; x < image->width; ++x) {
+ outp->b = inp[0];
+ outp->g = inp[1];
+ outp->r = inp[2];
+ outp->a = 255;
+ ++outp;
+ inp += 3;
+ }
+ }
+ free(buffer);
+
+ return 1;
+}
+
/*
=item read_8bit_data
for (i = 0; i < image_count; ++i) {
ico_image_t const *image = images + i;
- if (image->width < 1 || image->width > 255) {
+ if (image->width < 1 || image->width > 256) {
*error = ICOERR_Invalid_Width;
return 0;
}
- if (image->height < 1 || image->height > 255) {
+ if (image->height < 1 || image->height > 256) {
*error = ICOERR_Invalid_Height;
return 0;
}
=head1 AUTHOR
-Tony Cook <tony@imager.perl.org>
+Tony Cook <tonyc@cpan.org>
=head1 REVISION