ImageCapture/ImageObserver/BMP.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2003,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 <OPENR/OFbkImage.h>
00013 #include <OPENR/OSyslog.h>
00014 #include "BMP.h"
00015 
00016 bool 
00017 BMP::SaveYCrCb2RGB(char* path,
00018                    OFbkImageVectorData* imageVec, OFbkImageLayer layer)
00019 {
00020     if (layer == ofbkimageLAYER_C) return false;
00021 
00022     byte pixels[3];
00023     OFbkImageInfo* info = imageVec->GetInfo(layer);
00024     byte*          data = imageVec->GetData(layer);
00025     
00026     OFbkImage yImage(info, data, ofbkimageBAND_Y);
00027     OFbkImage crImage(info, data, ofbkimageBAND_Cr);
00028     OFbkImage cbImage(info, data, ofbkimageBAND_Cb);
00029 
00030     BMPHeader     header;
00031     BMPInfoHeader infoheader;
00032 
00033     infoheader.width     = yImage.Width();
00034     infoheader.height    = yImage.Height();
00035     infoheader.imagesize = yImage.Width() * yImage.Height() * 3;
00036 
00037     header.size = infoheader.imagesize + 54;
00038 
00039     FILE* fp = fopen(path, "w");
00040     if (fp == 0) {
00041         OSYSLOG1((osyslogERROR, "can't open %s", path));
00042         return false;
00043     }
00044 
00045     SaveBMPHeader(fp, header);
00046     SaveBMPInfoHeader(fp, infoheader);
00047 
00048     for (int y = infoheader.height - 1 ; y >= 0; y--) {
00049         for (int x = 0; x < infoheader.width; x++) {
00050             YCrCb2RGB(yImage.Pixel(x, y),
00051                       crImage.Pixel(x, y),
00052                       cbImage.Pixel(x, y),
00053                       &pixels[R_PIXEL], &pixels[G_PIXEL], &pixels[B_PIXEL]);
00054             fwrite(pixels, 1, 3, fp);
00055         }
00056     }
00057 
00058     fclose(fp);
00059     return true;
00060 }
00061 
00062 bool 
00063 BMP::SaveLayerC(char* basepath, OFbkImageVectorData* imageVec)
00064 {
00065     byte pixels[3];
00066     char path[128];
00067     OFbkImageInfo* info = imageVec->GetInfo(ofbkimageLAYER_C);
00068     byte*          data = imageVec->GetData(ofbkimageLAYER_C);
00069     
00070     OFbkImage cdtImage(info, data, ofbkimageBAND_CDT);
00071 
00072     BMPHeader     header;
00073     BMPInfoHeader infoheader;
00074 
00075     infoheader.width     = cdtImage.Width();
00076     infoheader.height    = cdtImage.Height();
00077     infoheader.imagesize = cdtImage.Width() * cdtImage.Height() * 3;
00078 
00079     header.size = infoheader.imagesize + 54;
00080 
00081     for (int i = 0; i < ocdtNUM_CHANNELS; i++) {
00082 
00083         byte plane = 0x01 << i;
00084         sprintf(path, "%s%d.BMP", basepath, i);
00085         
00086         FILE* fp = fopen(path, "w");
00087         if (fp == 0) {
00088             OSYSLOG1((osyslogERROR, "can't open %s", path));
00089             return false;
00090         }
00091 
00092         SaveBMPHeader(fp, header);
00093         SaveBMPInfoHeader(fp, infoheader);
00094 
00095         for (int y = infoheader.height - 1 ; y >= 0; y--) {
00096             for (int x = 0; x < infoheader.width; x++) {
00097                 if (cdtImage.Pixel(x, y) & plane) {
00098                     pixels[R_PIXEL] = pixels[G_PIXEL] = pixels[B_PIXEL] = 255;
00099                 } else {
00100                     pixels[R_PIXEL] = pixels[G_PIXEL] = pixels[B_PIXEL] = 0;
00101                 }
00102                 fwrite(pixels, 1, 3, fp);
00103             }
00104         }
00105 
00106         fclose(fp);
00107     }
00108 
00109     return true;
00110 }
00111 
00112 bool 
00113 BMP::SaveRaw2Gray(char* path,
00114                   byte* image, int width, int height, int skip)
00115 {
00116     byte pixels[3];
00117     BMPHeader     header;
00118     BMPInfoHeader infoheader;
00119 
00120     infoheader.width     = width;
00121     infoheader.height    = height;
00122     infoheader.imagesize = width * height * 3;
00123 
00124     header.size = infoheader.imagesize + 54;
00125 
00126     FILE* fp = fopen(path, "w");
00127     if (fp == 0) {
00128         OSYSLOG1((osyslogERROR, "can't open %s", path));
00129         return false;
00130     }
00131 
00132     SaveBMPHeader(fp, header);
00133     SaveBMPInfoHeader(fp, infoheader);
00134 
00135     for (int y = infoheader.height - 1 ; y >= 0; y--) {
00136         for (int x = 0; x < infoheader.width; x++) {
00137             byte pixel = *(image + (width + skip) * y + x);
00138             pixels[R_PIXEL] = pixels[G_PIXEL] = pixels[B_PIXEL] = pixel;
00139             fwrite(pixels, 1, 3, fp);
00140         }
00141     }
00142 
00143     fclose(fp);
00144     return true;
00145 }
00146                
00147 void
00148 BMP::SaveBMPHeader(FILE* fp, const BMPHeader& header)
00149 {
00150     fwrite(header.magic, 1, 2, fp);
00151     write_longword(fp, header.size);
00152     write_word(fp, header.reserved1);
00153     write_word(fp, header.reserved2);
00154     write_longword(fp, header.offset);
00155 }
00156 
00157 void
00158 BMP::SaveBMPInfoHeader(FILE* fp, const BMPInfoHeader& infoheader)
00159 {
00160     fwrite(&infoheader, sizeof(infoheader), 1, fp);
00161 }
00162 
00163 void
00164 BMP::YCrCb2RGB(byte y, byte cr, byte cb, byte* r, byte* g, byte* b)
00165 {
00166     // offset binary [0, 255] -> signed char [-128, 127]
00167     sbyte scr = (sbyte)(cr ^ 0x80);
00168     sbyte scb = (sbyte)(cb ^ 0x80);
00169 
00170     double Y  = (double)y / 255.0;   //  0.0 <= Y  <= 1.0
00171     double Cr = (double)scr / 128.0; // -1.0 <= Cr <  1.0
00172     double Cb = (double)scb / 128.0; // -1.0 <= Cb <  1.0
00173 
00174     double R = 255.0 * (Y + Cr);
00175     double G = 255.0 * (Y - 0.51*Cr - 0.19*Cb);
00176     double B = 255.0 * (Y + Cb);
00177 
00178     if (R > 255.0) {
00179         *r = 255;
00180     } else if (R < 0.0) {
00181         *r = 0;
00182     } else {
00183         *r = (byte)R;
00184     }
00185 
00186     if (G > 255.0) {
00187         *g = 255;
00188     } else if (G < 0.0) {
00189         *g = 0;
00190     } else {
00191         *g = (byte)G;
00192     }
00193 
00194     if (B > 255.0) {
00195         *b = 255;
00196     } else if (B < 0.0) {
00197         *b = 0;
00198     } else {
00199         *b = (byte)B;
00200     }
00201 }
00202 
00203 void
00204 BMP::write_word(FILE* fp, word w)
00205 {
00206     fputc(w & 0xff, fp);
00207     fputc((w >> 8) & 0xff, fp);
00208 }
00209 
00210 void
00211 BMP::write_longword(FILE* fp, longword l)
00212 {
00213     fputc(l & 0xff, fp);
00214     fputc((l >> 8) & 0xff, fp);
00215     fputc((l >> 16) & 0xff, fp);
00216     fputc((l >> 24) & 0xff, fp);
00217 }
00218 
00219 void
00220 BMP::write_slongword(FILE* fp, slongword sl)
00221 {
00222     fputc(sl & 0xff, fp);
00223     fputc((sl >> 8) & 0xff, fp);
00224     fputc((sl >> 16) & 0xff, fp);
00225     fputc((sl >> 24) & 0xff, fp);
00226 }

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