Go to the documentation of this file.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 #include <fstream>
00036
00037 #include "common/wave_ex.h"
00038 #include "perf/perf.h"
00039 #include "pgmppm/pgmppm.h"
00040 #include "util/parsing.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 struct context_t {
00055 context_t(void) throw() { this->clear(); }
00056 void clear(void) throw() {
00057 width = 0;
00058 height = 0;
00059 array = NULL;
00060 }
00061
00062
00063 int width;
00064 int height;
00065 pgmppm::color_t * array;
00066 };
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 static pgmppm::color_t
00077 getPixel
00078 (
00079 IN void * context,
00080 IN int x,
00081 IN int y
00082 )
00083 {
00084 context_t * ctx = (context_t *) context;
00085 ASSERT(ctx, "null");
00086 ASSERT(ctx->array, "null");
00087 ASSERT(x >= 0 && x < ctx->width, "bad x: %d", x);
00088 ASSERT(y >= 0 && y < ctx->height, "bad y: %d", y);
00089
00090 int idx = (y * ctx->width) + x;
00091 return ctx->array[idx];
00092 }
00093
00094
00095
00096 static void
00097 writePpm
00098 (
00099 IO std::istream& stream,
00100 IN const char * filename
00101 )
00102 {
00103 ASSERT(stream.good(), "bad?");
00104 ASSERT(filename, "null");
00105
00106
00107 eParseBehavior parseFlags = eParse_Strip;
00108
00109
00110 std::string line = getNextLineFromStream(stream, parseFlags);
00111 std::string token;
00112
00113
00114 dictionary_t dict;
00115 getDictionaryFromString(line.c_str(), "first line of PPM input", dict);
00116 int width = atoi(getRequiredValue(dict, "width"));
00117 int height = atoi(getRequiredValue(dict, "height"));
00118 if (width < 2 || height < 2) {
00119 WAVE_EX(wex);
00120 wex << "Bad width or height: " << width << " x " << height;
00121 }
00122
00123
00124 context_t ctx;
00125 ctx.width = width;
00126 ctx.height = height;
00127 ctx.array = new pgmppm::color_t[width * height];
00128 ASSERT(ctx.array, "out of memory");
00129
00130
00131 int max_color = 255;
00132 pgmppm::color_t * p = ctx.array;
00133 int expectX = 0;
00134 int expectY = 0;
00135 while (!stream.eof()) {
00136 line = getNextLineFromStream(stream, parseFlags);
00137
00138 getDictionaryFromString(line.c_str(), "PPM data line", dict);
00139 int x = atoi(getRequiredValue(dict, "x"));
00140 int y = atoi(getRequiredValue(dict, "y"));
00141 int r = atoi(getRequiredValue(dict, "r"));
00142 int g = atoi(getRequiredValue(dict, "g"));
00143 int b = atoi(getRequiredValue(dict, "b"));
00144
00145 if (x != expectX || y != expectY) {
00146 WAVE_EX(wex);
00147 wex << "unexpected or out of order x,y values?\n";
00148 wex << " expected: (" << expectX << ", " << expectY << ")\n";
00149 wex << " read: (" << x << ", " << y << ")";
00150 }
00151 if (r < 0 || r > max_color ||
00152 g < 0 || g > max_color ||
00153 b < 0 || b > max_color) {
00154 WAVE_EX(wex);
00155 wex << "invalid color value:\n";
00156 wex << " red : " << r << "\n";
00157 wex << " green: " << g << "\n";
00158 wex << " blue : " << b << "\n";
00159 }
00160
00161 pgmppm::color_t c;
00162 c.red = r;
00163 c.blue = b;
00164 c.green = g;
00165 *p = c;
00166 ++p;
00167
00168 ++expectX;
00169 if (expectX >= width) {
00170 expectX = 0;
00171 ++expectY;
00172 }
00173
00174 if (expectY >= height) {
00175 break;
00176 }
00177 }
00178
00179
00180 std::ofstream outfile(filename);
00181 if (!outfile.good()) {
00182 WAVE_EX(wex);
00183 wex << "Failed to open file for writing: " << filename;
00184 }
00185 pgmppm::writePpm(outfile, width, height, max_color, getPixel,
00186 (void *) &ctx);
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 int
00198 main
00199 (
00200 IN int argc,
00201 IN const char * argv[]
00202 )
00203 {
00204 ASSERT(2 == argc, "usage: writePpm <ppm-filename>");
00205 const char * filename = argv[1];
00206
00207 int retval = 0;
00208
00209 try {
00210 perf::Timer timer("overall timer");
00211 writePpm(std::cin, filename);
00212
00213 } catch (std::exception& e) {
00214 DPRINTF("Exception: %s", e.what());
00215 retval = 1;
00216 }
00217
00218
00219 perf::dumpTimingSummary(std::cerr);
00220 return retval;
00221 }
00222