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;
colorspace_t cspace
The colorspace of the image.
Fawkes library namespace.
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.