00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "pgmppm.h"
00039
00040 #include "common/wave_ex.h"
00041
00042 #include "perf/perf.h"
00043
00044 #include "util/token_stream.h"
00045
00046
00047 namespace pgmppm {
00048
00049
00050
00051 static const int s_maxGray = 256;
00052 static const int s_maxColor = 256;
00053
00054 static const char * s_magicPGM = "P5";
00055 static const char * s_magicPPM = "P6";
00056
00057
00058
00059
00060
00061
00062
00063
00064 void
00065 writePgm
00066 (
00067 IO std::ostream& out,
00068 IN int width,
00069 IN int height,
00070 IN int max_gray,
00071 IN pgm_pixel_fn fn,
00072 IN void * context
00073 )
00074 {
00075 perf::Timer timer("pgmppm::writePgm");
00076 ASSERT(out.good(), "bad?");
00077 ASSERT(width > 0, "bad width: %d", width);
00078 ASSERT(height > 0, "bad height: %d", height);
00079 ASSERT(max_gray > 0 && max_gray < s_maxGray, "bad max_gray: %d",
00080 max_gray);
00081 ASSERT(fn, "null pgm callback");
00082
00083
00084 int bpv = 0;
00085 if (max_gray < 256) {
00086 bpv = 1;
00087 } else if (max_gray < 65536) {
00088 bpv = 2;
00089 } else {
00090 ASSERT(false, "Bad max_gray?");
00091 }
00092 ASSERT(bpv > 0, "Bad bytes per value: %d", bpv);
00093
00094
00095 out << s_magicPGM << "\n";
00096 out << width << " " << height << "\n";
00097 out << max_gray << "\n";
00098
00099
00100 for (int j = 0; j < height; ++j) {
00101 for (int i = 0; i < width; ++i) {
00102 int val = fn(context, i, j);
00103
00104 ASSERT(val >= 0 && val <= max_gray,
00105 "Bad pixel value [%d, %d] = %d", i, j, val);
00106
00107
00108 out.put((byte_t) val);
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 }
00119 }
00120 }
00121
00122
00123
00124 void
00125 writePpm
00126 (
00127 IO std::ostream& out,
00128 IN int width,
00129 IN int height,
00130 IN int max_color,
00131 IN ppm_pixel_fn fn,
00132 IN void * context
00133 )
00134 {
00135 perf::Timer timer("pgmppm::writePpm");
00136 ASSERT(out.good(), "bad?");
00137 ASSERT(width > 0, "Bad width: %d", width);
00138 ASSERT(height > 0, "bad height: %d", height);
00139 ASSERT(max_color > 0 && max_color < s_maxColor, "Bad max_color: %d",
00140 max_color);
00141 ASSERT(fn, "null ppm callback");
00142
00143
00144
00145 out << s_magicPPM << "\n";
00146 out << width << " " << height << "\n";
00147 out << max_color << "\n";
00148
00149 for (int j = 0; j < height; ++j) {
00150 for (int i = 0; i < width; ++i) {
00151 color_t c = fn(context, i, j);
00152 ASSERT(c.red >= 0 && c.red <= max_color,
00153 "bad red val: %d", c.red);
00154 ASSERT(c.green >= 0 && c.green <= max_color,
00155 "bad green val: %d", c.green );
00156 ASSERT(c.blue >= 0 && c.blue <= max_color,
00157 "bad blue val: %d", c.blue );
00158
00159 out.put((byte_t) c.red);
00160 out.put((byte_t) c.green);
00161 out.put((byte_t) c.blue);
00162 }
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 bool
00175 readPgm
00176 (
00177 IO std::istream& in,
00178 IN notify_size_fn notify,
00179 IN pgm_write_pixel_fn write_pixel,
00180 IN void * context
00181 )
00182 {
00183 perf::Timer timer("pgmppm::readPgm");
00184 ASSERT(in.good(), "bad?");
00185 ASSERT(notify, "null");
00186 ASSERT(write_pixel, "null");
00187
00188
00189 std::string token;
00190 expectToken(in, s_magicPGM);
00191
00192 int width = readInteger(in, token);
00193 int length = readInteger(in, token);
00194 if (width <= 0 || length <= 0) {
00195 WAVE_EX(wex);
00196 wex << "Bad width (" << width << ") ";
00197 wex << "or length (" << length << ")";
00198 }
00199
00200 int max_val = readInteger(in, token);
00201 if (max_val <= 0 || max_val >= s_maxGray) {
00202 WAVE_EX(wex);
00203 wex << "Unsupported max_gray: " << max_val;
00204 }
00205
00206 DPRINTF("Reading PGM of dimensions %d x %d, max_gray = %d",
00207 width, length, max_val);
00208 if (!notify(context, width, length, max_val))
00209 return false;
00210
00211 for (int j = 0; j < length; ++j) {
00212 for (int i = 0; i < width; ++i) {
00213 char c;
00214 if (!in.good()) {
00215 WAVE_EX(wex);
00216 wex << "Could not read entire pgm image";
00217 }
00218 in.get(c);
00219 byte_t b = c;
00220 write_pixel(context, i, j, b);
00221 }
00222 }
00223
00224 return true;
00225 }
00226
00227
00228
00229 };
00230