00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00167 sbyte scr = (sbyte)(cr ^ 0x80);
00168 sbyte scb = (sbyte)(cb ^ 0x80);
00169
00170 double Y = (double)y / 255.0;
00171 double Cr = (double)scr / 128.0;
00172 double Cb = (double)scb / 128.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 }