ImageObserver/util/BMP.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2004 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include "BMP.h"
00016 
00017 bool
00018 BMP::SaveCDT(char* path, byte y_segment,
00019              byte cr_max, byte cr_min, byte cb_max, byte cb_min)
00020 {
00021     byte pixels[3];
00022     BMPHeader     header;
00023     BMPInfoHeader infoheader;
00024     bool noCDT;
00025 
00026     infoheader.width     = 256;
00027     infoheader.height    = 256;
00028     infoheader.imagesize = 256 * 256 * 3;
00029 
00030     header.size = infoheader.imagesize + 54;
00031     
00032     FILE* fp = fopen(path, "wb");
00033     if (fp == 0) {
00034         fprintf(stderr, "BMP::SaveCDT() : can't open %s\n", path);
00035         return false;
00036     }
00037 
00038     SaveBMPHeader(fp, header);
00039     SaveBMPInfoHeader(fp, infoheader);
00040 
00041     if (cr_max == 128 && cr_min == 128 && cb_max == 128 && cb_min == 128) {
00042         noCDT = true;
00043     } else {
00044         noCDT = false;
00045     }
00046 
00047 
00048     for (int y = 0 ; y < infoheader.height; y++) {
00049         for (int x = 0; x < infoheader.width; x++) {
00050 
00051             YCrCb2RGB(y_segment * 8 + 4, y, x,
00052                       &pixels[R_PIXEL], &pixels[G_PIXEL], &pixels[B_PIXEL]);
00053             
00054             if (noCDT != true) {
00055                 if ((y == cr_min && cb_min <= x && x <= cb_max) ||
00056                     (y == cr_max && cb_min <= x && x <= cb_max) ||
00057                     (x == cb_min && cr_min <= y && y <= cr_max) ||
00058                     (x == cb_max && cr_min <= y && y <= cr_max)) {
00059                     pixels[R_PIXEL] = pixels[G_PIXEL] = pixels[B_PIXEL] = 0;
00060                 }
00061             }
00062 
00063             fwrite(pixels, 1, 3, fp);
00064         }
00065     }
00066 
00067     fclose(fp);
00068     return true;
00069 }
00070 
00071 bool
00072 BMP::SaveRawDataAsCDT(char* basepath, byte* data, size_t w, size_t h)
00073 {
00074     byte pixels[3];
00075     byte* buf;
00076     char path[128];
00077 
00078     size_t offY  = 0;
00079     size_t offCr = w;
00080     size_t offCb = 2 * w;
00081     size_t skip  = 2 * w;
00082 
00083     BMPHeader     header;
00084     BMPInfoHeader infoheader;
00085 
00086     infoheader.width     = 256;
00087     infoheader.height    = 256;
00088     infoheader.imagesize = 256 * 256 * 3;
00089 
00090     header.size = infoheader.imagesize + 54;
00091 
00092     buf = (byte*)malloc(256*256);
00093     if (buf == 0) return false;
00094 
00095     for (int yseg = 0; yseg < 32; yseg++) {
00096 
00097         sprintf(path, "%s%02d.bmp", basepath, yseg);
00098         byte ypix_min = 8 * yseg;
00099         byte ypix_max = 8 * yseg + 7;
00100         memset(buf, 0, 256*256);
00101         
00102         for (int y = 0; y < h; y++) {
00103             for (int x = 0; x < w; x++) {
00104                 byte ypix = *(data + offY + (w + skip) * y + x);
00105                 if (ypix_min <= ypix && ypix <= ypix_max) {
00106                     byte cr = *(data + offCr + (w + skip) * y + x);
00107                     byte cb = *(data + offCb + (w + skip) * y + x);
00108                     *(buf + 256 * cr + cb) = 1;
00109                 }
00110             }
00111         }
00112 
00113         FILE* fp = fopen(path, "w");
00114         if (fp == 0) {
00115             fprintf(stderr,
00116                     "BMP::SaveRawDataAsCDT() : can't open %s\n", path);
00117             return false;
00118         }
00119 
00120         SaveBMPHeader(fp, header);
00121         SaveBMPInfoHeader(fp, infoheader);
00122 
00123         for (int y = 0; y < 256; y++) { // Cr
00124             for (int x = 0; x < 256; x++) { // Cb
00125                 if (*(buf + 256 * y + x) != 0) {
00126                     YCrCb2RGB(ypix_min + 4, y, x,
00127                               &pixels[R_PIXEL],
00128                               &pixels[G_PIXEL],
00129                               &pixels[B_PIXEL]);
00130                 } else {
00131                     pixels[R_PIXEL] = pixels[G_PIXEL] = pixels[B_PIXEL] = 0;
00132                 }
00133                 fwrite(pixels, 1, 3, fp);
00134             }
00135         }
00136 
00137         fclose(fp);
00138     }
00139 
00140     free(buf);
00141 
00142     return true;
00143 }
00144 
00145 void
00146 BMP::SaveBMPHeader(FILE* fp, const BMPHeader& header)
00147 {
00148     fwrite(header.magic, 1, 2, fp);
00149     write_longword(fp, header.size);
00150     write_word(fp, header.reserved1);
00151     write_word(fp, header.reserved2);
00152     write_longword(fp, header.offset);
00153 }
00154 
00155 void
00156 BMP::SaveBMPInfoHeader(FILE* fp, const BMPInfoHeader& infoheader)
00157 {
00158     fwrite(&infoheader, sizeof(infoheader), 1, fp);
00159 }
00160 
00161 void
00162 BMP::YCrCb2RGB(byte y, byte cr, byte cb, byte* r, byte* g, byte* b)
00163 {
00164     double Y  = (double)y / 255.0;                  //  0.0 <= Y  <= 1.0
00165     double Cr = ((double)cr * 2.0 - 255.0) / 255.0; // -1.0 <= Cr <= 1.0
00166     double Cb = ((double)cb * 2.0 - 255.0) / 255.0; // -1.0 <= Cb <= 1.0
00167 
00168     double R = 255.0 * (Y + Cr);
00169     double G = 255.0 * (Y - 0.51*Cr - 0.19*Cb);
00170     double B = 255.0 * (Y + Cb);
00171 
00172     if (R > 255.0) {
00173         *r = 255;
00174     } else if (R < 0.0) {
00175         *r = 0;
00176     } else {
00177         *r = (byte)R;
00178     }
00179 
00180     if (G > 255.0) {
00181         *g = 255;
00182     } else if (G < 0.0) {
00183         *g = 0;
00184     } else {
00185         *g = (byte)G;
00186     }
00187 
00188     if (B > 255.0) {
00189         *b = 255;
00190     } else if (B < 0.0) {
00191         *b = 0;
00192     } else {
00193         *b = (byte)B;
00194     }
00195 }
00196 
00197 void
00198 BMP::write_word(FILE* fp, word w)
00199 {
00200     fputc(w & 0xff, fp);
00201     fputc((w >> 8) & 0xff, fp);
00202 }
00203 
00204 void
00205 BMP::write_longword(FILE* fp, longword l)
00206 {
00207     fputc(l & 0xff, fp);
00208     fputc((l >> 8) & 0xff, fp);
00209     fputc((l >> 16) & 0xff, fp);
00210     fputc((l >> 24) & 0xff, fp);
00211 }
00212 
00213 void
00214 BMP::write_slongword(FILE* fp, slongword sl)
00215 {
00216     fputc(sl & 0xff, fp);
00217     fputc((sl >> 8) & 0xff, fp);
00218     fputc((sl >> 16) & 0xff, fp);
00219     fputc((sl >> 24) & 0xff, fp);
00220 }

Generated on Sun Dec 2 23:04:28 2007 for openSDK by  doxygen 1.3.9.1