28static int compress_row(
unsigned char *uncompressed_row,
int length);
29static int build_rle_packet(
unsigned char *row,
int packet_type,
int length,
unsigned char *
data);
93 int bitmap_size = 0, info_size, total_size, padding;
94 int i, row, xpos, pixel;
96 unsigned char *uncompressed_row =
NULL, *uncompressed_row_start =
NULL;
97 FILE *tmpfile_for_compression =
NULL;
105 if (compression == 1 && !
out->seek) {
107 if ((tmpfile_for_compression =
tmpfile()) ==
NULL) {
119 bitmap_size = ((im->
sx * (im->
trueColor ? 24 : 8)) / 8) * im->
sy;
133 total_size = 14 + info_size + bitmap_size;
137 gdBMPPutInt(
out, total_size);
138 gdBMPPutWord(
out, 0);
139 gdBMPPutWord(
out, 0);
140 gdBMPPutInt(
out, 14 + info_size);
144 gdBMPPutInt(
out, im->
sx);
145 gdBMPPutInt(
out, im->
sy);
146 gdBMPPutWord(
out, 1);
149 gdBMPPutInt(
out, bitmap_size);
156 padding = ((int)(im->
trueColor ? 3 : 1) * im->
sx) % 4;
158 padding = 4 - padding;
172 uncompressed_row = uncompressed_row_start = (
unsigned char *)
gdCalloc(
gdImageSX(im) * 2,
sizeof(
char));
173 if (!uncompressed_row) {
179 for (row = (im->
sy - 1); row >= 0; row--) {
184 for (xpos = 0; xpos < im->
sx; xpos++) {
194 for (xpos = padding; xpos > 0; --xpos) {
198 int compressed_size = 0;
199 uncompressed_row = uncompressed_row_start;
200 if ((compressed_size = compress_row(uncompressed_row,
gdImageSX(im))) < 0) {
204 bitmap_size += compressed_size;
214 if (compression && uncompressed_row) {
226 gdBMPPutInt(
out, total_size + bitmap_size);
230 gdBMPPutInt(
out, bitmap_size);
234 for (row = (im->
sy - 1); row >= 0; row--) {
235 for (xpos = 0; xpos < im->
sx; xpos++) {
244 for (xpos = padding; xpos > 0; --xpos) {
252 if (tmpfile_for_compression) {
253 unsigned char* copy_buffer =
NULL;
257 copy_buffer = (
unsigned char *)
gdMalloc(1024 *
sizeof(
unsigned char));
258 if (copy_buffer ==
NULL) {
262 while ((buffer_size =
gdGetBuf(copy_buffer, 1024,
out)) != EOF) {
263 if (buffer_size == 0) {
266 gdPutBuf(copy_buffer , buffer_size, out_original);
277 if (tmpfile_for_compression) {
281 fclose(tmpfile_for_compression);
283 tmpfile_for_compression =
NULL;
287 out_original->
gd_free(out_original);
292static int compress_row(
unsigned char *row,
int length)
295 int compressed_length = 0;
296 int pixel = 0, compressed_run = 0, rle_compression = 0;
297 unsigned char *uncompressed_row =
NULL, *uncompressed_rowp =
NULL, *uncompressed_start =
NULL;
299 uncompressed_row = (
unsigned char *)
gdMalloc(length);
300 if (!uncompressed_row) {
304 memcpy(uncompressed_row, row, length);
305 uncompressed_start = uncompressed_rowp = uncompressed_row;
307 for (pixel = 0; pixel < length; pixel++) {
308 if (compressed_run == 0) {
309 uncompressed_row = uncompressed_rowp;
316 if (compressed_run == 1) {
318 if (memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) {
324 if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) != 0) {
326 rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row);
327 row += rle_compression;
328 compressed_length += rle_compression;
336 if (compressed_run >= 128 || memcmp(uncompressed_rowp, uncompressed_rowp - 1, 1) == 0) {
338 rle_compression = build_rle_packet(row, rle_type, compressed_run, uncompressed_row);
339 row += rle_compression;
340 compressed_length += rle_compression;
352 if (compressed_run) {
353 compressed_length += build_rle_packet(row, rle_type, compressed_run, uncompressed_row);
356 gdFree(uncompressed_start);
358 return compressed_length;
361static int build_rle_packet(
unsigned char *row,
int packet_type,
int length,
unsigned char *
data)
363 int compressed_size = 0;
364 if (length < 1 || length > 128) {
371 for (i = 0; i < length; i++) {
372 compressed_size += 2;
387 compressed_size = 2 + length;
404 return compressed_size;
447 if (bmp_read_header(infile, hdr)) {
452 if (hdr->
magic != 0x4d42) {
462 if (bmp_read_info(infile, info)) {
475 if (info->
depth >= 16) {
487 switch (info->
depth) {
490 error = bmp_read_1bit(im, infile, info, hdr);
494 error = bmp_read_4bit(im, infile, info, hdr);
498 error = bmp_read_8bit(im, infile, info, hdr);
504 error = bmp_read_direct(im, infile, info, hdr);
549 if (bmp_read_windows_v3_info(infile, info)) {
554 if (bmp_read_os2_v1_info(infile, info)) {
559 if (bmp_read_os2_v2_info(infile, info)) {
631 char useless_bytes[24];
648 if (!
gdGetBuf(useless_bytes, 24, infile)) {
672 int ypos = 0, xpos = 0, row = 0;
673 int padding = 0, alpha = 0, red = 0, green = 0, blue = 0;
674 signed short int data = 0;
682 if (info->
depth == 24) {
683 BMP_DEBUG(
printf(
"Bitfield compression isn't supported for 24-bit\n"));
691 if (info->
depth != 8) {
697 if (info->
depth != 4) {
718 padding = ((int)(info->
depth / 8) * info->
width) % 4;
720 padding = 4 - padding;
724 for (ypos = 0; ypos < info->
height; ++ypos) {
728 row = info->
height - ypos - 1;
731 for (xpos = 0; xpos < info->
width; xpos++) {
732 if (info->
depth == 16) {
737 red = ((
data & 0x7C00) >> 10) << 3;
738 green = ((
data & 0x3E0) >> 5) << 3;
739 blue = (
data & 0x1F) << 3;
741 }
else if (info->
depth == 24) {
753 for (xpos = padding; xpos > 0; --xpos) {
768 for (i = 0; i <
count; i++) {
787 int ypos = 0, xpos = 0, row = 0, index = 0;
788 int padding = 0, current_byte = 0, bit = 0;
815 padding = (info->
width + 7) / 8 % 4;
817 padding = 4 - padding;
820 for (ypos = 0; ypos < info->
height; ++ypos) {
824 row = info->
height - ypos - 1;
827 for (xpos = 0; xpos < info->
width; xpos += 8) {
833 for (bit = 0; bit < 8; bit++) {
834 index = ((current_byte & (0x80 >> bit)) != 0 ? 0x01 : 0x00);
835 if (im->
open[index]) {
840 if ((xpos + bit) >= info->
width) {
846 for (xpos = padding; xpos > 0; --xpos) {
857 int ypos = 0, xpos = 0, row = 0, index = 0;
858 int padding = 0, current_byte = 0;
885 padding = ((int)
ceil(0.5 * info->
width)) % 4;
887 padding = 4 - padding;
892 for (ypos = 0; ypos < info->
height; ++ypos) {
896 row = info->
height - ypos - 1;
899 for (xpos = 0; xpos < info->
width; xpos += 2) {
904 index = (current_byte >> 4) & 0x0f;
905 if (im->
open[index]) {
911 if (xpos >= info->
width) {
915 index = current_byte & 0x0f;
916 if (im->
open[index]) {
922 for (xpos = padding; xpos > 0; --xpos) {
931 if (bmp_read_rle(im, infile, info)) {
944 int ypos = 0, xpos = 0, row = 0, index = 0;
972 padding = (1 * info->
width) % 4;
974 padding = 4 - padding;
979 for (ypos = 0; ypos < info->
height; ++ypos) {
983 row = info->
height - ypos - 1;
986 for (xpos = 0; xpos < info->
width; ++xpos) {
991 if (im->
open[index]) {
997 for (xpos = padding; xpos > 0; --xpos) {
1006 if (bmp_read_rle(im, infile, info)) {
1019 int ypos = 0, xpos = 0, row = 0, index = 0;
1020 int rle_length = 0, rle_data = 0;
1023 int pixels_per_byte = 8 / info->
depth;
1025 for (ypos = 0; ypos < info->
height && xpos <= info->
width;) {
1029 row = info->
height - ypos - 1;
1032 if (im->
open[rle_data]) {
1033 im->
open[rle_data] = 0;
1036 for (i = 0; (i < rle_length) && (xpos < info->
width);) {
1037 for (
j = 1; (
j <= pixels_per_byte) && (xpos < info->
width) && (i < rle_length);
j++, xpos++, i++) {
1038 index = (rle_data & (((1 << info->
depth) - 1) << (8 - (
j * info->
depth)))) >> (8 - (
j * info->
depth));
1039 if (im->
open[index]) {
1040 im->
open[index] = 0;
1048 for (i = 0; (i < rle_data) && (xpos < info->
width); i += pixels_per_byte) {
1049 int max_pixels = pixels_per_byte;
1056 if (rle_data - i < max_pixels) {
1057 max_pixels = rle_data - i;
1060 for (
j = 1; (
j <= max_pixels) && (xpos < info->
width);
j++, xpos++) {
1061 int temp = (index >> (8 - (
j * info->
depth))) & ((1 << info->
depth) - 1);
1062 if (im->
open[temp]) {
1070 if (padding % 2 && !
gdGetByte(&index, infile)) {
printf(string $format, mixed ... $values)
header(string $header, bool $replace=true, int $response_code=0)
count(Countable|array $value, int $mode=COUNT_NORMAL)
#define BMP_RLE_ENDOFBITMAP
#define BMP_RLE_ENDOFLINE
memset(ptr, 0, type->size)
#define gdImageBlue(im, c)
#define gdTrueColorGetBlue(c)
void * gdDPExtractData(struct gdIOCtx *ctx, int *size)
#define gdTrueColorGetGreen(c)
#define gdTrueColorGetRed(c)
gdIOCtx * gdNewFileCtx(FILE *)
#define gdImageGreen(im, c)
gdIOCtx * gdNewDynamicCtx(int, void *)
#define gdTrueColor(r, g, b)
gdIOCtx * gdNewDynamicCtxEx(int size, void *data, int freeFlag)
#define gdImageRed(im, c)
void * gdImageBmpPtr(gdImagePtr im, int *size, int compression)
void gdImageBmp(gdImagePtr im, FILE *outFile, int compression)
gdImagePtr gdImageCreateFromBmpCtx(gdIOCtxPtr infile)
gdImagePtr gdImageCreateFromBmpPtr(int size, void *data)
gdImagePtr gdImageCreateFromBmp(FILE *inFile)
void gdImageBmpCtx(gdImagePtr im, gdIOCtxPtr out, int compression)
int gdGetIntLSB(signed int *result, gdIOCtx *ctx)
long gdTell(gdIOCtx *ctx)
int gdGetBuf(void *buf, int size, gdIOCtx *ctx)
int gdSeek(gdIOCtx *ctx, const int pos)
void Putchar(int c, gdIOCtx *ctx)
int gdGetByte(int *result, gdIOCtx *ctx)
int gdPutBuf(const void *buf, int size, gdIOCtx *ctx)
void gdPutC(const unsigned char c, gdIOCtx *ctx)
int gdGetWordLSB(signed short int *result, gdIOCtx *ctx)
struct gdIOCtx * gdIOCtxPtr
#define gdCalloc(nmemb, size)
gdImagePtr gdImageCreate(int sx, int sy)
int gdImageGetPixel(gdImagePtr im, int x, int y)
void gdImageDestroy(gdImagePtr im)
gdImagePtr gdImageCreateTrueColor(int sx, int sy)
void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
signed short int reserved2
signed short int reserved1
signed short int numplanes
void(* gd_free)(struct gdIOCtx *)