00001
00002
00003
00004
00005
00006
00007
00008
00009
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++) {
00124 for (int x = 0; x < 256; x++) {
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;
00165 double Cr = ((double)cr * 2.0 - 255.0) / 255.0;
00166 double Cb = ((double)cb * 2.0 - 255.0) / 255.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 }