int R2Image:: ReadBMP(const char *filename) { // Open file FILE *fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Unable to open image file: %s\n", filename); return 0; } /* Read file header */ BITMAPFILEHEADER bmfh; bmfh.bfType = WordReadLE(fp); bmfh.bfSize = DWordReadLE(fp); bmfh.bfReserved1 = WordReadLE(fp); bmfh.bfReserved2 = WordReadLE(fp); bmfh.bfOffBits = DWordReadLE(fp); /* Check file header */ assert(bmfh.bfType == BMP_BF_TYPE); /* ignore bmfh.bfSize */ /* ignore bmfh.bfReserved1 */ /* ignore bmfh.bfReserved2 */ assert(bmfh.bfOffBits == BMP_BF_OFF_BITS); /* Read info header */ BITMAPINFOHEADER bmih; bmih.biSize = DWordReadLE(fp); bmih.biWidth = LongReadLE(fp); bmih.biHeight = LongReadLE(fp); bmih.biPlanes = WordReadLE(fp); bmih.biBitCount = WordReadLE(fp); bmih.biCompression = DWordReadLE(fp); bmih.biSizeImage = DWordReadLE(fp); bmih.biXPelsPerMeter = LongReadLE(fp); bmih.biYPelsPerMeter = LongReadLE(fp); bmih.biClrUsed = DWordReadLE(fp); bmih.biClrImportant = DWordReadLE(fp); // Check info header assert(bmih.biSize == BMP_BI_SIZE); assert(bmih.biWidth > 0); assert(bmih.biHeight > 0); assert(bmih.biPlanes == 1); assert(bmih.biBitCount == 24); /* RGB */ assert(bmih.biCompression == BI_RGB); /* RGB */ int lineLength = bmih.biWidth * 3; /* RGB */ if ((lineLength % 4) != 0) lineLength = (lineLength / 4 + 1) * 4; assert(bmih.biSizeImage == (unsigned int) lineLength * (unsigned int) bmih.biHeight); // Assign width, height, and number of pixels width = bmih.biWidth; height = bmih.biHeight; npixels = width * height; // Allocate unsigned char buffer for reading pixels int rowsize = 3 * width; if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4; int nbytes = bmih.biSizeImage; unsigned char *buffer = new unsigned char [nbytes]; if (!buffer) { fprintf(stderr, "Unable to allocate temporary memory for BMP file"); fclose(fp); return 0; } // Read buffer fseek(fp, (long) bmfh.bfOffBits, SEEK_SET); if (fread(buffer, 1, bmih.biSizeImage, fp) != bmih.biSizeImage) { fprintf(stderr, "Error while reading BMP file %s", filename); return 0; } // Close file fclose(fp); // Allocate pixels for image pixels = new R2Pixel [ width * height ]; if (!pixels) { fprintf(stderr, "Unable to allocate memory for BMP file"); fclose(fp); return 0; } // Assign pixels for (int j = 0; j < height; j++) { unsigned char *p = &buffer[j * rowsize]; for (int i = 0; i < width; i++) { double b = (double) *(p++) / 255; double g = (double) *(p++) / 255; double r = (double) *(p++) / 255; R2Pixel pixel(r, g, b, 1); SetPixel(i, j, pixel); } } // Free unsigned char buffer for reading pixels delete [] buffer; // Return success return 1; }
int R2Image:: ReadBMP(const char *filename) { // Open file FILE *fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "Unable to open image file: %s", filename); return 0; } /* Read file header */ BITMAPFILEHEADER bmfh; bmfh.bfType = WordReadLE(fp); bmfh.bfSize = DWordReadLE(fp); bmfh.bfReserved1 = WordReadLE(fp); bmfh.bfReserved2 = WordReadLE(fp); bmfh.bfOffBits = DWordReadLE(fp); /* Check file header */ assert(bmfh.bfType == BMP_BF_TYPE); /* ignore bmfh.bfSize */ /* ignore bmfh.bfReserved1 */ /* ignore bmfh.bfReserved2 */ assert(bmfh.bfOffBits == BMP_BF_OFF_BITS); /* Read info header */ BITMAPINFOHEADER bmih; bmih.biSize = DWordReadLE(fp); bmih.biWidth = LongReadLE(fp); bmih.biHeight = LongReadLE(fp); bmih.biPlanes = WordReadLE(fp); bmih.biBitCount = WordReadLE(fp); bmih.biCompression = DWordReadLE(fp); bmih.biSizeImage = DWordReadLE(fp); bmih.biXPelsPerMeter = LongReadLE(fp); bmih.biYPelsPerMeter = LongReadLE(fp); bmih.biClrUsed = DWordReadLE(fp); bmih.biClrImportant = DWordReadLE(fp); // Check info header assert(bmih.biSize == BMP_BI_SIZE); assert(bmih.biWidth > 0); assert(bmih.biHeight > 0); assert(bmih.biPlanes == 1); assert(bmih.biBitCount == 24); /* RGB */ assert(bmih.biCompression == BI_RGB); /* RGB */ int lineLength = bmih.biWidth * 3; /* RGB */ if ((lineLength % 4) != 0) lineLength = (lineLength / 4 + 1) * 4; assert(bmih.biSizeImage == (unsigned int) lineLength * (unsigned int) bmih.biHeight); // Assign width, height, and ncomponents width = bmih.biWidth; height = bmih.biHeight; ncomponents = 3; rowsize = ncomponents * width; if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4; // Allocate pixels int nbytes = bmih.biSizeImage; pixels = new unsigned char [nbytes]; if (!pixels) { fprintf(stderr, "Unable to allocate memory for BMP file"); fclose(fp); return 0; } // Read pixels fseek(fp, (long) bmfh.bfOffBits, SEEK_SET); if (fread(pixels, 1, bmih.biSizeImage, fp) != bmih.biSizeImage) { fprintf(stderr, "Error while reading BMP file %s", filename); return 0; } // Swap blue and red in each pixel for (int j = 0; j < height; j++) { unsigned char *p = &pixels[j * rowsize]; for (int i = 0; i < width; i++) { unsigned char c = *p; *(p) = *(p+2); *(p+2) = c; p += 3; } } // Close file fclose(fp); // Return success return 1; }