int R2Image:: WriteBMP(const char *filename) const { // Open file FILE *fp = fopen(filename, "wb"); if (!fp) { fprintf(stderr, "Unable to open image file: %s\n", filename); return 0; } // Compute number of bytes in row int rowsize = 3 * width; if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4; // Write file header BITMAPFILEHEADER bmfh; bmfh.bfType = BMP_BF_TYPE; bmfh.bfSize = BMP_BF_OFF_BITS + rowsize * height; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = BMP_BF_OFF_BITS; WordWriteLE(bmfh.bfType, fp); DWordWriteLE(bmfh.bfSize, fp); WordWriteLE(bmfh.bfReserved1, fp); WordWriteLE(bmfh.bfReserved2, fp); DWordWriteLE(bmfh.bfOffBits, fp); // Write info header BITMAPINFOHEADER bmih; bmih.biSize = BMP_BI_SIZE; bmih.biWidth = width; bmih.biHeight = height; bmih.biPlanes = 1; bmih.biBitCount = 24; /* RGB */ bmih.biCompression = BI_RGB; /* RGB */ bmih.biSizeImage = rowsize * (unsigned int) bmih.biHeight; /* RGB */ bmih.biXPelsPerMeter = 2925; bmih.biYPelsPerMeter = 2925; bmih.biClrUsed = 0; bmih.biClrImportant = 0; DWordWriteLE(bmih.biSize, fp); LongWriteLE(bmih.biWidth, fp); LongWriteLE(bmih.biHeight, fp); WordWriteLE(bmih.biPlanes, fp); WordWriteLE(bmih.biBitCount, fp); DWordWriteLE(bmih.biCompression, fp); DWordWriteLE(bmih.biSizeImage, fp); LongWriteLE(bmih.biXPelsPerMeter, fp); LongWriteLE(bmih.biYPelsPerMeter, fp); DWordWriteLE(bmih.biClrUsed, fp); DWordWriteLE(bmih.biClrImportant, fp); // Write image, swapping blue and red in each pixel int pad = rowsize - width * 3; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { const R2Pixel& pixel = (*this)[i][j]; double r = 255.0 * pixel.Red(); double g = 255.0 * pixel.Green(); double b = 255.0 * pixel.Blue(); if (r >= 255) r = 255; if (g >= 255) g = 255; if (b >= 255) b = 255; fputc((unsigned char) b, fp); fputc((unsigned char) g, fp); fputc((unsigned char) r, fp); } // Pad row for (int i = 0; i < pad; i++) fputc(0, fp); } // Close file fclose(fp); // Return success return 1; }
int R2Image:: WriteBMP(const char *filename) const { // Check ncomponents assert(ncomponents == 3); // Open file FILE *fp = fopen(filename, "wb"); if (!fp) { fprintf(stderr, "Unable to open image file: %s", filename); return 0; } // Write file header BITMAPFILEHEADER bmfh; bmfh.bfType = BMP_BF_TYPE; bmfh.bfSize = BMP_BF_OFF_BITS + rowsize * height; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = BMP_BF_OFF_BITS; WordWriteLE(bmfh.bfType, fp); DWordWriteLE(bmfh.bfSize, fp); WordWriteLE(bmfh.bfReserved1, fp); WordWriteLE(bmfh.bfReserved2, fp); DWordWriteLE(bmfh.bfOffBits, fp); // Write info header BITMAPINFOHEADER bmih; bmih.biSize = BMP_BI_SIZE; bmih.biWidth = width; bmih.biHeight = height; bmih.biPlanes = 1; bmih.biBitCount = 24; /* RGB */ bmih.biCompression = BI_RGB; /* RGB */ bmih.biSizeImage = rowsize * (unsigned int) bmih.biHeight; /* RGB */ bmih.biXPelsPerMeter = 2925; bmih.biYPelsPerMeter = 2925; bmih.biClrUsed = 0; bmih.biClrImportant = 0; DWordWriteLE(bmih.biSize, fp); LongWriteLE(bmih.biWidth, fp); LongWriteLE(bmih.biHeight, fp); WordWriteLE(bmih.biPlanes, fp); WordWriteLE(bmih.biBitCount, fp); DWordWriteLE(bmih.biCompression, fp); DWordWriteLE(bmih.biSizeImage, fp); LongWriteLE(bmih.biXPelsPerMeter, fp); LongWriteLE(bmih.biYPelsPerMeter, fp); DWordWriteLE(bmih.biClrUsed, fp); DWordWriteLE(bmih.biClrImportant, fp); // Write image, swapping blue and red in each pixel int pad = rowsize - width * 3; for (int j = 0; j < height; j++) { // Write row of pixels BGR unsigned char *p = &pixels[j * rowsize]; for (int i = 0; i < width; i++) { fputc(*(p+2), fp); fputc(*(p+1), fp); fputc(*(p+0), fp); p += 3; } // Pad row for (int i = 0; i < pad; i++) fputc(0, fp); } // Close file fclose(fp); // Return success return 1; }