161 BYTE pbm_id1[] = { 0x50, 0x31 };
162 BYTE pbm_id2[] = { 0x50, 0x34 };
163 BYTE pgm_id1[] = { 0x50, 0x32 };
164 BYTE pgm_id2[] = { 0x50, 0x35 };
165 BYTE ppm_id1[] = { 0x50, 0x33 };
166 BYTE ppm_id2[] = { 0x50, 0x36 };
167 BYTE signature[2] = { 0, 0 };
169 io->read_proc(signature, 1,
sizeof(pbm_id1), handle);
171 if (memcmp(pbm_id1, signature,
sizeof(pbm_id1)) == 0)
174 if (memcmp(pbm_id2, signature,
sizeof(pbm_id2)) == 0)
177 if (memcmp(pgm_id1, signature,
sizeof(pgm_id1)) == 0)
180 if (memcmp(pgm_id2, signature,
sizeof(pgm_id2)) == 0)
183 if (memcmp(ppm_id1, signature,
sizeof(ppm_id1)) == 0)
186 if (memcmp(ppm_id2, signature,
sizeof(ppm_id2)) == 0)
213Load(FreeImageIO *io, fi_handle handle,
int ,
int ,
void * ) {
214 char id_one = 0, id_two = 0;
216 FIBITMAP *dib =
nullptr;
224 FREE_IMAGE_TYPE image_type = FIT_BITMAP;
230 io->read_proc(&id_one, 1, 1, handle);
231 io->read_proc(&id_two, 1, 1, handle);
233 if ((id_one !=
'P') || (id_two <
'1') || (id_two >
'6')) {
235 throw "Invalid magic number";
240 int width =
GetInt(io, handle);
241 int height =
GetInt(io, handle);
243 if((id_two ==
'2') || (id_two ==
'5') || (id_two ==
'3') || (id_two ==
'6')) {
247 throw (
const char*)
nullptr;
259 dib = FreeImage_Allocate(width, height, 1);
266 image_type = FIT_UINT16;
267 dib = FreeImage_AllocateT(image_type, width, height);
270 dib = FreeImage_Allocate(width, height, 8);
278 image_type = FIT_RGB16;
279 dib = FreeImage_AllocateT(image_type, width, height);
282 dib = FreeImage_Allocate(width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
288 throw "DIB allocation failed";
297 pal = FreeImage_GetPalette(dib);
298 pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
299 pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
304 for (y = 0; y < height; y++) {
305 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
307 for (x = 0; x < width; x++) {
308 if (
GetInt(io, handle) == 0)
309 bits[x >> 3] |= (0x80 >> (x & 0x7));
311 bits[x >> 3] &= (0xFF7F >> (x & 0x7));
317 for (y = 0; y < height; y++) {
318 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
320 for (x = 0; x < line; x++) {
321 io->read_proc(&bits[x], 1, 1, handle);
332 if(image_type == FIT_BITMAP) {
335 pal = FreeImage_GetPalette(dib);
337 for (i = 0; i < 256; i++) {
340 pal[i].rgbBlue = (BYTE)i;
348 for (y = 0; y < height; y++) {
349 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
351 for (x = 0; x < width; x++) {
352 level =
GetInt(io, handle);
353 bits[x] = (BYTE)((255 * level) /
s_maxval);
359 for (y = 0; y < height; y++) {
360 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
362 for (x = 0; x < width; x++) {
363 io->read_proc(&level, 1, 1, handle);
364 bits[x] = (BYTE)((255 * (
int)level) /
s_maxval);
369 else if(image_type == FIT_UINT16) {
375 for (y = 0; y < height; y++) {
376 WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
378 for (x = 0; x < width; x++) {
379 level =
GetInt(io, handle);
380 bits[x] = (WORD)level;
386 for (y = 0; y < height; y++) {
387 WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
389 for (x = 0; x < width; x++) {
401 if(image_type == FIT_BITMAP) {
407 for (y = 0; y < height; y++) {
408 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
410 for (x = 0; x < width; x++) {
411 level =
GetInt(io, handle);
412 bits[FI_RGBA_RED] = (BYTE)((255 * level) /
s_maxval);
413 level =
GetInt(io, handle);
414 bits[FI_RGBA_GREEN] = (BYTE)((255 * level) /
s_maxval);
415 level =
GetInt(io, handle);
416 bits[FI_RGBA_BLUE] = (BYTE)((255 * level) /
s_maxval);
424 for (y = 0; y < height; y++) {
425 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
427 for (x = 0; x < width; x++) {
428 io->read_proc(&level, 1, 1, handle);
429 bits[FI_RGBA_RED] = (BYTE)((255 * (
int)level) /
s_maxval);
431 io->read_proc(&level, 1, 1, handle);
432 bits[FI_RGBA_GREEN] = (BYTE)((255 * (
int)level) /
s_maxval);
434 io->read_proc(&level, 1, 1, handle);
435 bits[FI_RGBA_BLUE] = (BYTE)((255 * (
int)level) /
s_maxval);
442 else if(image_type == FIT_RGB16) {
448 for (y = 0; y < height; y++) {
449 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
451 for (x = 0; x < width; x++) {
452 level =
GetInt(io, handle);
453 bits[x].red = (WORD)level;
454 level =
GetInt(io, handle);
455 bits[x].green = (WORD)level;
456 level =
GetInt(io, handle);
457 bits[x].blue = (WORD)level;
463 for (y = 0; y < height; y++) {
464 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
466 for (x = 0; x < width; x++) {
470 bits[x].green = level;
472 bits[x].blue = level;
481 }
catch (
const char *text) {
482 if(dib) FreeImage_Unload(dib);
484 if(
nullptr != text) {
509Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle,
int ,
int flags,
void * ) {
530 if(!dib || !handle)
return FALSE;
532 FREE_IMAGE_TYPE image_type = FreeImage_GetImageType(dib);
534 int bpp = FreeImage_GetBPP(dib);
535 int width = FreeImage_GetWidth(dib);
536 int height = FreeImage_GetHeight(dib);
575 if (flags == PNM_SAVE_RAW)
580 sprintf(buffer,
"P%d\n%d %d\n", magic, width, height);
581 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
585 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
591 if(image_type == FIT_BITMAP) {
595 if (flags == PNM_SAVE_RAW) {
596 for (y = 0; y < height; y++) {
598 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
600 for (x = 0; x < width; x++) {
601 io->write_proc(&bits[FI_RGBA_RED], 1, 1, handle);
602 io->write_proc(&bits[FI_RGBA_GREEN], 1, 1, handle);
603 io->write_proc(&bits[FI_RGBA_BLUE], 1, 1, handle);
611 for (y = 0; y < height; y++) {
613 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
615 for (x = 0; x < width; x++) {
616 sprintf(buffer,
"%3d %3d %3d ", bits[FI_RGBA_RED], bits[FI_RGBA_GREEN], bits[FI_RGBA_BLUE]);
618 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
624 sprintf(buffer,
"\n");
625 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
639 if (flags == PNM_SAVE_RAW) {
640 for (y = 0; y < height; y++) {
642 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
644 for (x = 0; x < width; x++) {
645 io->write_proc(&bits[x], 1, 1, handle);
651 for (y = 0; y < height; y++) {
653 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
655 for (x = 0; x < width; x++) {
656 sprintf(buffer,
"%3d ", bits[x]);
658 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
664 sprintf(buffer,
"\n");
665 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
678 if (flags == PNM_SAVE_RAW) {
679 for(y = 0; y < height; y++) {
681 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
683 for(x = 0; x < (int)FreeImage_GetLine(dib); x++)
684 io->write_proc(&bits[x], 1, 1, handle);
689 for (y = 0; y < height; y++) {
691 BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
693 for (x = 0; x < (int)FreeImage_GetLine(dib) * 8; x++) {
694 color = (bits[x>>3] & (0x80 >> (x & 0x07))) != 0;
696 sprintf(buffer,
"%c ", color ?
'1':
'0');
698 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
704 sprintf(buffer,
"\n");
705 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
717 else if(image_type == FIT_UINT16) {
718 if (flags == PNM_SAVE_RAW) {
719 for (y = 0; y < height; y++) {
721 WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
723 for (x = 0; x < width; x++) {
730 for (y = 0; y < height; y++) {
732 WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
734 for (x = 0; x < width; x++) {
735 sprintf(buffer,
"%5d ", bits[x]);
737 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
743 sprintf(buffer,
"\n");
744 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
752 else if(image_type == FIT_RGB16) {
753 if (flags == PNM_SAVE_RAW) {
754 for (y = 0; y < height; y++) {
756 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
758 for (x = 0; x < width; x++) {
767 for (y = 0; y < height; y++) {
769 FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
771 for (x = 0; x < width; x++) {
772 sprintf(buffer,
"%5d %5d %5d ", bits[x].red, bits[x].green, bits[x].blue);
774 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);
780 sprintf(buffer,
"\n");
781 io->write_proc(&buffer, (
unsigned int)strlen(buffer), 1, handle);