24 #include <core/exception.h>
25 #include <core/exceptions/system.h>
26 #include <fvutils/color/conversions.h>
27 #include <fvutils/color/yuv.h>
28 #include <fvutils/color/yuvrgb.h>
29 #include <fvutils/writers/pnm.h>
37 namespace firevision {
46 PNMWriter::PNMWriter(PNMFormat format) :
Writer(
"pnm")
48 this->format = format;
50 buffer_size = calc_buffer_size();
51 buffer = (
unsigned char *)malloc(buffer_size);
52 buffer_start = buffer;
62 const char * filename,
69 this->format = format;
71 this->height = height;
73 buffer_size = calc_buffer_size();
74 buffer = (
unsigned char *)malloc(buffer_size);
75 buffer_start = buffer;
81 if (
cspace != YUV422_PLANAR) {
82 throw Exception(
"Unsupported colorspace, PNM can only write YUV422_PLANAR images");
85 buffer = buffer_start;
86 memset(buffer, 0, buffer_size);
88 buffer += write_header();
90 unsigned char *yp, *up, *vp;
91 unsigned char y1, y2, u, v;
93 yp = yuv422_planar_buf;
94 up = YUV422_PLANAR_U_PLANE(yuv422_planar_buf, width, height);
95 vp = YUV422_PLANAR_V_PLANE(yuv422_planar_buf, width, height);
97 if ((format == PNM_PBM) || (format == PNM_PBM_ASCII)) {
98 unsigned char byte = 0;
99 unsigned int num_bits = 0;
101 for (
unsigned int i = 0; i < height; ++i) {
104 for (
unsigned int j = 0; j < width; ++j) {
111 if (format == PNM_PBM) {
112 byte |= (y2 << (7 - num_bits++));
120 sprintf((
char *)buffer,
"%c ", y2);
124 if ((format == PNM_PBM) && (num_bits != 0)) {
128 }
else if ((format == PNM_PGM) || (format == PNM_PGM_ASCII)) {
129 for (
unsigned int i = 0; i < height; ++i) {
130 for (
unsigned int j = 0; j < width; ++j) {
132 if (format == PNM_PGM) {
136 sprintf((
char *)buffer,
"%3c ", y1);
142 }
else if (format == PNM_PPM) {
143 convert(YUV422_PLANAR, RGB, yuv422_planar_buf, buffer, width, height);
145 }
else if (format == PNM_PPM_ASCII) {
146 unsigned char r, g, b;
148 for (
unsigned int i = 0; i < height; ++i) {
149 for (
unsigned int j = 0; j < (width / 2); ++j) {
155 pixel_yuv_to_rgb(y1, u, v, &r, &g, &b);
156 sprintf((
char *)buffer,
"%3c %3c %3c ", r, g, b);
159 pixel_yuv_to_rgb(y2, u, v, &r, &g, &b);
160 sprintf((
char *)buffer,
"%3c %3c %3c ", r, g, b);
168 PNMWriter::format2string(PNMFormat format)
171 case PNM_PBM:
return "P4";
172 case PNM_PBM_ASCII:
return "P1";
173 case PNM_PGM:
return "P5";
174 case PNM_PGM_ASCII:
return "P2";
175 case PNM_PPM:
return "P6";
176 case PNM_PPM_ASCII:
return "P3";
178 default:
throw Exception(
"Unknown PNMFormat");
183 PNMWriter::write_header(
bool simulate)
185 unsigned int rv = 25;
191 sprintf((
char *)buffer,
"%s %10u %10u\n", format2string(format), width, height);
198 sprintf((
char *)buffer,
"%s %10u %10u 255\n", format2string(format), width, height);
208 case PNM_PPM_ASCII: rv += 4;
break;
220 throw Exception(
"Could not open file for writing");
223 if (fwrite(buffer_start, buffer_size, 1, fp) != 1) {
230 PNMWriter::calc_buffer_size()
232 unsigned int rv = write_header(
true);
234 unsigned int num_row_bytes = 0;
239 num_row_bytes = width / 8;
240 if ((width % 8) != 0) {
248 num_row_bytes = 2 * width;
251 case PNM_PGM: num_row_bytes = width;
break;
253 case PNM_PGM_ASCII: num_row_bytes = width * 4;
break;
255 case PNM_PPM: num_row_bytes = 3 * width;
break;
264 num_row_bytes = width * 13;
270 rv += num_row_bytes * height;
Base class for exceptions in Fawkes.
PNMWriter(PNMFormat format)
Constructor.
virtual void set_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer.
virtual void write()
Write to file.
Interface to write images.
colorspace_t cspace
The colorspace of the image.
virtual void set_filename(const char *filename)
Set filename.
char * filename
The complete filename.
Fawkes library namespace.