200 void CByteImage::FreeMemory()
218 static int my_strcmpi(
const char *pString1,
const char *pString2)
220 for (
int i = 0;; i++)
222 const unsigned char c1 = (
unsigned char) toupper((
int) pString1[i]);
223 const unsigned char c2 = (
unsigned char) toupper((
int) pString2[i]);
225 if (c1 ==
'\0' || c1 != c2)
234 const char *pBeginEnding = pFileName + strlen(pFileName) - 4;
236 return LoadFromFileBMP(pFileName);
238 return LoadFromFilePNM(pFileName);
245 const char *pBeginEnding = pFileName + strlen(pFileName) - 4;
247 return SaveToFileBMP(pFileName);
249 return SaveToFilePNM(pFileName);
255 bool CByteImage::LoadFromFileBMP(
const char *pFileName)
257 const unsigned short MB = 0x4d42;
262 FILE *f = fopen(pFileName,
"rb");
266 unsigned char szHeader[4096];
268 if (fread(szHeader, 14, 1, f) != 1)
274 myBITMAPFILEHEADER bitmapFileHeader;
276 #ifdef IVT_BIG_ENDIAN
283 bitmapFileHeader.bfType = *((
unsigned short *) (szHeader));
284 bitmapFileHeader.bfSize = *((
unsigned int *) (szHeader + 2));
285 bitmapFileHeader.bfReserved1 = *((
unsigned short *) (szHeader + 6));
286 bitmapFileHeader.bfReserved2 = *((
unsigned short *) (szHeader + 8));
287 bitmapFileHeader.bfOffBits = *((
unsigned int *) (szHeader + 10));
290 if (bitmapFileHeader.bfType != MB || bitmapFileHeader.bfReserved1 != 0 || bitmapFileHeader.bfReserved2 != 0 || bitmapFileHeader.bfOffBits >= 4096)
296 if (fread(szHeader + 14, bitmapFileHeader.bfOffBits - 14, 1, f) != 1)
302 myBITMAPINFOHEADER bitmapInfoHeader;
303 unsigned char *pBitmapInfoHeaderPosition = szHeader + 14;
305 #ifdef IVT_BIG_ENDIAN
307 bitmapInfoHeader.biWidth =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 4)));
311 bitmapInfoHeader.biCompression =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 16)));
312 bitmapInfoHeader.biSizeImage =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 20)));
313 bitmapInfoHeader.biXPelsPerMeter =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 24)));
314 bitmapInfoHeader.biYPelsPerMeter =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 28)));
315 bitmapInfoHeader.biClrUsed =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 32)));
316 bitmapInfoHeader.biClrImportant =
invert_byte_order_int(*((
unsigned int *) (pBitmapInfoHeaderPosition + 36)));
318 bitmapInfoHeader.biSize = *((
unsigned int *) (pBitmapInfoHeaderPosition));
319 bitmapInfoHeader.biWidth = *((
unsigned int *) (pBitmapInfoHeaderPosition + 4));
320 bitmapInfoHeader.biHeight = *((
int *) (pBitmapInfoHeaderPosition + 8));
321 bitmapInfoHeader.biPlanes = *((
unsigned short *) (pBitmapInfoHeaderPosition + 12));
322 bitmapInfoHeader.biBitCount = *((
unsigned short *) (pBitmapInfoHeaderPosition + 14));
323 bitmapInfoHeader.biCompression = *((
unsigned int *) (pBitmapInfoHeaderPosition + 16));
324 bitmapInfoHeader.biSizeImage = *((
unsigned int *) (pBitmapInfoHeaderPosition + 20));
325 bitmapInfoHeader.biXPelsPerMeter = *((
unsigned int *) (pBitmapInfoHeaderPosition + 24));
326 bitmapInfoHeader.biYPelsPerMeter = *((
unsigned int *) (pBitmapInfoHeaderPosition + 28));
327 bitmapInfoHeader.biClrUsed = *((
unsigned int *) (pBitmapInfoHeaderPosition + 32));
328 bitmapInfoHeader.biClrImportant = *((
unsigned int *) (pBitmapInfoHeaderPosition + 36));
331 if ((bitmapInfoHeader.biBitCount != 8 && bitmapInfoHeader.biBitCount != 24 && bitmapInfoHeader.biBitCount != 32) || bitmapInfoHeader.biWidth <= 0)
337 if (bitmapInfoHeader.biCompression != 0)
343 if (bitmapInfoHeader.biBitCount != 8 && bitmapInfoHeader.biClrUsed > 256)
350 width = bitmapInfoHeader.biWidth;
351 height = abs(bitmapInfoHeader.biHeight);
353 int nReadBytesPerPixel;
355 const int nTableSize = bitmapInfoHeader.biClrUsed == 0 ? 1024 : 4 * bitmapInfoHeader.biClrUsed;
356 unsigned char index_table[1024];
357 memcpy(index_table, pBitmapInfoHeaderPosition + bitmapInfoHeader.biSize, nTableSize);
359 bool bIndexed =
false;
361 if (bitmapInfoHeader.biBitCount == 8)
363 if (bitmapFileHeader.bfOffBits - 14 - bitmapInfoHeader.biSize != nTableSize)
371 bool bGrayScale =
true;
373 for (
int i = 0; i < nTableSize; i += 4)
375 if (index_table[i] != index_table[i + 1] || index_table[i] != index_table[i + 2])
383 if (index_table[i] != (i >> 2))
391 nReadBytesPerPixel = 1;
397 nReadBytesPerPixel = 1;
402 switch (bitmapInfoHeader.biBitCount)
407 nReadBytesPerPixel = 3;
413 nReadBytesPerPixel = 4;
423 const int padding_bytes = ((
width * nReadBytesPerPixel) % 4 == 0) ? 0 : 4 - ((
width * nReadBytesPerPixel) % 4);
429 unsigned char *pTempBuffer =
new unsigned char[(
width * nReadBytesPerPixel + padding_bytes) * height +
EXTRA_BYTES];
433 if (fread(pTempBuffer, (
width * nReadBytesPerPixel + padding_bytes) *
height, 1, f) != 1)
437 delete [] pTempBuffer;
441 if (bitmapInfoHeader.biHeight < 0)
445 const int write_width_bytes = 3 *
width;
446 const int width_bytes = nReadBytesPerPixel *
width;
447 const int aligned_width_bytes = width_bytes + padding_bytes;
449 unsigned char *pHelper1 =
pixels;
450 unsigned char *pHelper2 = pTempBuffer;
452 if (nReadBytesPerPixel == 1)
455 for (
int i = 0; i <
height; i++)
457 for (
int j = 0, k = 0; j < width_bytes; j++, k += 3)
459 pHelper1[k] = index_table[pHelper2[j] << 2];
460 pHelper1[k + 1] = index_table[(pHelper2[j] << 2) + 1];
461 pHelper1[k + 2] = index_table[(pHelper2[j] << 2) + 2];
464 pHelper1 += write_width_bytes;
465 pHelper2 += aligned_width_bytes;
471 for (
int i = 0; i <
height; i++)
473 for (
int j = 0, k = 0; j < width_bytes; j += nReadBytesPerPixel, k += 3)
475 pHelper1[k] = pHelper2[j + 2];
476 pHelper1[k + 1] = pHelper2[j + 1];
477 pHelper1[k + 2] = pHelper2[j];
480 pHelper1 += write_width_bytes;
481 pHelper2 += aligned_width_bytes;
487 const int aligned_width_bytes = width + padding_bytes;
489 unsigned char *pHelper1 =
pixels;
490 unsigned char *pHelper2 = pTempBuffer;
495 for (
int i = 0; i <
height; i++)
497 for (
int j = 0; j <
width; j++)
498 pHelper1[j] = index_table[pHelper2[j << 2]];
501 pHelper2 += aligned_width_bytes;
507 for (
int i = 0; i <
height; i++)
509 memcpy(pHelper1, pHelper2, width);
512 pHelper2 += aligned_width_bytes;
521 const int write_width_bytes = 3 *
width;
522 const int width_bytes = nReadBytesPerPixel *
width;
523 const int aligned_width_bytes = width_bytes + padding_bytes;
525 unsigned char *pHelper1 =
pixels;
526 unsigned char *pHelper2 = pTempBuffer + aligned_width_bytes * height - aligned_width_bytes;
528 if (nReadBytesPerPixel == 1)
531 for (
int i = 0; i <
height; i++)
533 for (
int j = 0, k = 0; j < width_bytes; j++, k += 3)
535 pHelper1[k] = index_table[pHelper2[j] << 2];
536 pHelper1[k + 1] = index_table[(pHelper2[j] << 2) + 1];
537 pHelper1[k + 2] = index_table[(pHelper2[j] << 2) + 2];
540 pHelper1 += write_width_bytes;
541 pHelper2 -= aligned_width_bytes;
547 for (
int i = 0; i <
height; i++)
549 for (
int j = 0, k = 0; j < width_bytes; j += nReadBytesPerPixel, k += 3)
551 pHelper1[k] = pHelper2[j + 2];
552 pHelper1[k + 1] = pHelper2[j + 1];
553 pHelper1[k + 2] = pHelper2[j];
556 pHelper1 += write_width_bytes;
557 pHelper2 -= aligned_width_bytes;
563 const int aligned_width_bytes = width + padding_bytes;
565 unsigned char *pHelper1 =
pixels;
566 unsigned char *pHelper2 = pTempBuffer + aligned_width_bytes * height - aligned_width_bytes;
571 for (
int i = 0; i <
height; i++)
573 for (
int j = 0; j <
width; j++)
574 pHelper1[j] = index_table[pHelper2[j] << 2];
577 pHelper2 -= aligned_width_bytes;
583 for (
int i = 0; i <
height; i++)
585 memcpy(pHelper1, pHelper2, width);
588 pHelper2 -= aligned_width_bytes;
595 delete [] pTempBuffer;
600 bool CByteImage::SaveToFileBMP(
const char *pFileName)
const
602 if (!
pixels || !width || !height)
605 const unsigned short MB = 0x4d42;
608 myBITMAPFILEHEADER bitmapFileHeader;
609 bitmapFileHeader.bfType = MB;
610 bitmapFileHeader.bfReserved1 = 0;
611 bitmapFileHeader.bfReserved2 = 0;
613 myBITMAPINFOHEADER bitmapInfoHeader;
614 bitmapInfoHeader.biSize = 40;
615 bitmapInfoHeader.biWidth =
width;
616 bitmapInfoHeader.biHeight =
height;
617 bitmapInfoHeader.biPlanes = 1;
618 bitmapInfoHeader.biXPelsPerMeter = 0;
619 bitmapInfoHeader.biYPelsPerMeter = 0;
620 bitmapInfoHeader.biClrUsed = 0;
621 bitmapInfoHeader.biClrImportant = 0;
626 bitmapInfoHeader.biBitCount = 8;
627 bitmapInfoHeader.biSizeImage = (width + padding_bytes) * height;
628 bitmapInfoHeader.biCompression = 0;
629 bitmapFileHeader.bfOffBits = 14 + 40 + 1024;
630 bitmapFileHeader.bfSize = bitmapFileHeader.bfOffBits + bitmapInfoHeader.biSizeImage;
635 bitmapInfoHeader.biBitCount = 24;
636 bitmapInfoHeader.biSizeImage = (width * 3 + padding_bytes) * height;
637 bitmapInfoHeader.biCompression = 0;
638 bitmapFileHeader.bfOffBits = 14 + 40;
639 bitmapFileHeader.bfSize = bitmapFileHeader.bfOffBits + bitmapInfoHeader.biSizeImage;
647 FILE *f = fopen(pFileName,
"wb");
651 unsigned char szHeader[14 + 40];
652 unsigned char *pBitmapInfoHeaderPosition = szHeader + 14;
654 #ifdef IVT_BIG_ENDIAN
663 *((
unsigned int *) (pBitmapInfoHeaderPosition + 4)) =
invert_byte_order_int(bitmapInfoHeader.biWidth);
664 *((
unsigned int *) (pBitmapInfoHeaderPosition + 8)) =
invert_byte_order_int(bitmapInfoHeader.biHeight);
667 *((
unsigned int *) (pBitmapInfoHeaderPosition + 16)) =
invert_byte_order_int(bitmapInfoHeader.biCompression);
668 *((
unsigned int *) (pBitmapInfoHeaderPosition + 20)) =
invert_byte_order_int(bitmapInfoHeader.biSizeImage);
669 *((
unsigned int *) (pBitmapInfoHeaderPosition + 24)) =
invert_byte_order_int(bitmapInfoHeader.biXPelsPerMeter);
670 *((
unsigned int *) (pBitmapInfoHeaderPosition + 28)) =
invert_byte_order_int(bitmapInfoHeader.biYPelsPerMeter);
671 *((
unsigned int *) (pBitmapInfoHeaderPosition + 32)) =
invert_byte_order_int(bitmapInfoHeader.biClrUsed);
672 *((
unsigned int *) (pBitmapInfoHeaderPosition + 36)) =
invert_byte_order_int(bitmapInfoHeader.biClrImportant);
674 *((
unsigned short *) (szHeader)) = bitmapFileHeader.bfType;
675 *((
unsigned int *) (szHeader + 2)) = bitmapFileHeader.bfSize;
676 *((
unsigned short *) (szHeader + 6)) = bitmapFileHeader.bfReserved1;
677 *((
unsigned short *) (szHeader + 8)) = bitmapFileHeader.bfReserved2;
678 *((
unsigned int *) (szHeader + 10)) = bitmapFileHeader.bfOffBits;
681 *((
unsigned int *) (pBitmapInfoHeaderPosition)) = bitmapInfoHeader.biSize;
682 *((
unsigned int *) (pBitmapInfoHeaderPosition + 4)) = bitmapInfoHeader.biWidth;
683 *((
unsigned int *) (pBitmapInfoHeaderPosition + 8)) = bitmapInfoHeader.biHeight;
684 *((
unsigned short *) (pBitmapInfoHeaderPosition + 12)) = bitmapInfoHeader.biPlanes;
685 *((
unsigned short *) (pBitmapInfoHeaderPosition + 14)) = bitmapInfoHeader.biBitCount;
686 *((
unsigned int *) (pBitmapInfoHeaderPosition + 16)) = bitmapInfoHeader.biCompression;
687 *((
unsigned int *) (pBitmapInfoHeaderPosition + 20)) = bitmapInfoHeader.biSizeImage;
688 *((
unsigned int *) (pBitmapInfoHeaderPosition + 24)) = bitmapInfoHeader.biXPelsPerMeter;
689 *((
unsigned int *) (pBitmapInfoHeaderPosition + 28)) = bitmapInfoHeader.biYPelsPerMeter;
690 *((
unsigned int *) (pBitmapInfoHeaderPosition + 32)) = bitmapInfoHeader.biClrUsed;
691 *((
unsigned int *) (pBitmapInfoHeaderPosition + 36)) = bitmapInfoHeader.biClrImportant;
695 if (fwrite(szHeader, 14 + 40, 1, f) != 1)
704 char szColorTable[1024];
706 for (
int offset = 0, i = 0; i < 256; i++, offset += 4)
708 szColorTable[offset] = i;
709 szColorTable[offset + 1] = i;
710 szColorTable[offset + 2] = i;
711 szColorTable[offset + 3] = 0;
715 if (fwrite(szColorTable, 1024, 1, f) != 1)
722 unsigned char *pTempBuffer =
new unsigned char[(width *
bytesPerPixel + padding_bytes) * height];
726 const int width_bytes = 3 *
width;
728 unsigned char *pHelper1 = pTempBuffer;
729 unsigned char *pHelper2 =
pixels + width * height * 3 - width_bytes;
732 for (
int i = 0; i <
height; i++)
734 for (
int j = 0; j < width_bytes; j += 3)
736 pHelper1[j] = pHelper2[j + 2];
737 pHelper1[j + 1] = pHelper2[j + 1];
738 pHelper1[j + 2] = pHelper2[j];
741 for (
int j = width_bytes; j < width_bytes + padding_bytes; j++)
744 pHelper1 += width_bytes + padding_bytes;
745 pHelper2 -= width_bytes;
750 const int width_bytes = 3 *
width;
752 unsigned char *pHelper = pTempBuffer;
753 unsigned char *pHelperR =
pixels + width * height -
width;
754 unsigned char *pHelperG = pHelperR + width *
height;
755 unsigned char *pHelperB = pHelperG + width *
height;
758 for (
int i = 0; i <
height; i++)
760 for (
int j = 0, offset = 0; j < width_bytes; j += 3, offset++)
762 pHelper[j] = pHelperB[offset];
763 pHelper[j + 1] = pHelperG[offset];
764 pHelper[j + 2] = pHelperR[offset];
767 for (
int j = width_bytes; j < width_bytes + padding_bytes; j++)
770 pHelper += width_bytes + padding_bytes;
778 unsigned char *pHelper1 = pTempBuffer;
779 unsigned char *pHelper2 =
pixels + width * height -
width;
782 for (
int i = 0; i <
height; i++)
784 for (
int j = 0; j <
width; j++)
785 pHelper1[j] = pHelper2[j];
787 for (
int j = width; j < width + padding_bytes; j++)
790 pHelper1 += width + padding_bytes;
796 if (fwrite(pTempBuffer, (width *
bytesPerPixel + padding_bytes) * height, 1, f) != 1)
798 delete [] pTempBuffer;
803 delete [] pTempBuffer;
810 bool CByteImage::LoadFromFilePNM(
const char *pFileName)
815 FILE *f = fopen(pFileName,
"rb");
819 int character, maxVal;
823 character = fgetc(f);
824 if (character !=
'P')
830 character = fgetc(f);
831 if (character !=
'5' && character !=
'6' )
837 if (character ==
'5')
851 character = fgetc(f);
852 }
while (character ==
' ' || character ==
'\n' || character ==
'\r');
855 while (character ==
'#')
857 while (fgetc(f) !=
'\n');
858 character = fgetc(f);
863 while (character !=
' ' && character !=
'\n' && character !=
'\r')
865 sNumber[idx++] =(char) character;
866 character = fgetc(f);
868 sscanf(sNumber,
"%d",&width);
872 character = fgetc(f);
873 }
while (character ==
' ' || character ==
'\n' || character ==
'\r');
876 while (character ==
'#')
878 while (fgetc(f) !=
'\n');
879 character = fgetc(f);
884 while (character !=
' ' && character !=
'\n' && character !=
'\r') {
885 sNumber[idx++] =(char) character;
886 character = fgetc(f);
888 sscanf(sNumber,
"%d",&height);
893 character = fgetc(f);
894 }
while (character ==
' ' || character ==
'\n' || character ==
'\r');
897 while (character ==
'#')
899 while (fgetc(f) !=
'\n');
900 character = fgetc(f);
905 while (character !=
' ' && character !=
'\n' && character !=
'\r')
907 sNumber[idx++] =(char) character;
908 character = fgetc(f);
910 sscanf(sNumber,
"%d",&maxVal);
933 bool CByteImage::SaveToFilePNM(
const char *pFileName)
const
935 if (!
pixels || !width || !height)
938 FILE *f = fopen(pFileName,
"wb");
945 if (fprintf(f,
"P5\n%d %d\n255\n", width, height) < 10)
954 if (fprintf(f,
"P6\n%d %d\n255\n",width , height) < 10)
977 const int nPixels = width *
height;
979 unsigned char *pTempBuffer =
new unsigned char[nPixels * 3];
980 const unsigned char *pHelperR =
pixels;
981 const unsigned char *pHelperG = pHelperR + nPixels;
982 const unsigned char *pHelperB = pHelperG + nPixels;
984 for (
int i = 0, offset = 0; i < nPixels; i++, offset += 3)
986 pTempBuffer[offset] = pHelperR[i];
987 pTempBuffer[offset + 1] = pHelperG[i];
988 pTempBuffer[offset + 2] = pHelperB[i];
991 if (fwrite(pTempBuffer, nPixels * 3, 1, f ) != 1)
993 delete [] pTempBuffer;
998 delete [] pTempBuffer;
ImageType
Enum specifying the supported image types.
bool m_bOwnMemory
Flag signaling if memory is to be freed or not.
void Set(int nImageWidth, int nImageHeight, ImageType imageType, bool bHeaderOnly=false)
Changes size and type of an image.
bool LoadFromFile(const char *pFileName)
Loads an image from a file.
bool SaveToFile(const char *pFileName) const
Saves an image to a file.
~CByteImage()
The destructor.
unsigned int invert_byte_order_int(unsigned int x)
static int my_strcmpi(const char *pString1, const char *pString2)
ImageType type
The type of the image.
int width
The width of the image in pixels.
int height
The height of the image in pixels.
CByteImage()
The default constructor.
unsigned char * pixels
The pointer to the the pixels.
bool IsCompatible(const CByteImage *pImage) const
Checks whether two images are compatible or not.
unsigned short invert_byte_order_short(unsigned short x)
Data structure for the representation of 8-bit grayscale images and 24-bit RGB (or HSV) color images ...
int bytesPerPixel
The number of bytes used for encoding one pixel.