24 #include <core/exception.h>
25 #include <core/exceptions/system.h>
26 #include <fvutils/writers/pnm.h>
27 #include <fvutils/color/conversions.h>
32 using namespace fawkes;
34 namespace firevision {
46 PNMWriter::PNMWriter(PNMFormat format)
49 this->format = format;
51 buffer_size = calc_buffer_size();
52 buffer = (
unsigned char *)malloc(buffer_size);
53 buffer_start = buffer;
67 this->format = format;
69 this->height = height;
71 buffer_size = calc_buffer_size();
72 buffer = (
unsigned char *)malloc(buffer_size);
73 buffer_start = buffer;
80 if (cspace != YUV422_PLANAR) {
81 throw Exception(
"Unsupported colorspace, PNM can only write YUV422_PLANAR images");
84 buffer = buffer_start;
85 memset(buffer, 0, buffer_size);
87 buffer += write_header();
89 unsigned char *yp, *up, *vp;
90 unsigned char y1, y2, u, v;
92 yp = yuv422_planar_buf;
93 up = YUV422_PLANAR_U_PLANE(yuv422_planar_buf, width, height);
94 vp = YUV422_PLANAR_V_PLANE(yuv422_planar_buf, width, height);
97 if ( (format == PNM_PBM) ||
98 (format == PNM_PBM_ASCII) ) {
100 unsigned char byte = 0;
101 unsigned int num_bits = 0;
103 for (
unsigned int i = 0; i < height; ++i) {
106 for (
unsigned int j = 0; j < width; ++j) {
113 if ( format == PNM_PBM ) {
114 byte |= (y2 << (7-num_bits++));
122 sprintf((
char *)buffer,
"%c ", y2);
126 if ((format == PNM_PBM) && (num_bits != 0)) {
130 }
else if ( (format == PNM_PGM) ||
131 (format == PNM_PGM_ASCII) ) {
133 for (
unsigned int i = 0; i < height; ++i) {
134 for (
unsigned int j = 0; j < width; ++j) {
136 if ( format == PNM_PGM ) {
140 sprintf((
char *)buffer,
"%3c ", y1);
146 }
else if ( format == PNM_PPM ) {
148 convert(YUV422_PLANAR, RGB, yuv422_planar_buf, buffer, width, height);
150 }
else if (format == PNM_PPM_ASCII) {
152 unsigned char r, g, b;
154 for (
unsigned int i = 0; i < height; ++i) {
155 for (
unsigned int j = 0; j < (width / 2); ++j) {
161 pixel_yuv_to_rgb(y1, u, v, &r, &g, &b);
162 sprintf((
char *)buffer,
"%3c %3c %3c ", r, g, b);
165 pixel_yuv_to_rgb(y2, u, v, &r, &g, &b);
166 sprintf((
char *)buffer,
"%3c %3c %3c ", r, g, b);
176 PNMWriter::format2string(PNMFormat format)
179 case PNM_PBM:
return "P4";
180 case PNM_PBM_ASCII:
return "P1";
181 case PNM_PGM:
return "P5";
182 case PNM_PGM_ASCII:
return "P2";
183 case PNM_PPM:
return "P6";
184 case PNM_PPM_ASCII:
return "P3";
192 PNMWriter::write_header(
bool simulate)
194 unsigned int rv = 25;
200 sprintf((
char *)buffer,
"%s %10u %10u\n", format2string(format), width, height);
207 sprintf((
char *)buffer,
"%s %10u %10u 255\n", format2string(format), width, height);
232 throw Exception(
"Could not open file for writing");
235 if (fwrite(buffer_start, buffer_size, 1, fp) != 1) {
244 PNMWriter::calc_buffer_size()
246 unsigned int rv = write_header(
true);
248 unsigned int num_row_bytes = 0;
253 num_row_bytes = width / 8;
254 if ((width % 8) != 0) {
262 num_row_bytes = 2 * width;
266 num_row_bytes = width;
270 num_row_bytes = width * 4;
274 num_row_bytes = 3 * width;
284 num_row_bytes = width * 13;
290 rv += num_row_bytes * height;
Interface to write images.
virtual void write()
Write to file.
Base class for exceptions in Fawkes.
PNMWriter(PNMFormat format)
Constructor.
virtual void set_filename(const char *filename)
Set filename.
virtual void set_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer.
char * filename
The complete filename.