|
From: <mor...@us...> - 2008-04-04 16:45:30
|
Revision: 91
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=91&view=rev
Author: morgan_quigley
Date: 2008-04-04 09:45:35 -0700 (Fri, 04 Apr 2008)
Log Message:
-----------
a header to wrap jpeg compression / decompression
Added Paths:
-----------
pkg/trunk/image_utils/include/
pkg/trunk/image_utils/include/image_utils/
pkg/trunk/image_utils/include/image_utils/jpeg_wrapper.h
Added: pkg/trunk/image_utils/include/image_utils/jpeg_wrapper.h
===================================================================
--- pkg/trunk/image_utils/include/image_utils/jpeg_wrapper.h (rev 0)
+++ pkg/trunk/image_utils/include/image_utils/jpeg_wrapper.h 2008-04-04 16:45:35 UTC (rev 91)
@@ -0,0 +1,128 @@
+#ifndef IMAGE_UTILS_JPEG_WRAPPER_H
+#define IMAGE_UTILS_JPEG_WRAPPER_H
+
+#include "ijg_libjpeg/ros_jpeg_mutex.h"
+extern "C"
+{
+#include "jpeglib.h"
+}
+
+class JpegWrapper
+{
+public:
+ JpegWrapper()
+ : raster_width(0), raster_height(0), raster(NULL),
+ raster_alloc_size(0)
+ {
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ dinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&dinfo);
+ }
+
+ ~JpegWrapper()
+ {
+ jpeg_destroy_compress(&cinfo);
+ jpeg_destroy_decompress(&dinfo);
+ if (raster)
+ delete[] raster;
+ }
+
+ inline int width() { return raster_width; }
+ inline int height() { return raster_height; }
+ inline int raster_size() { return 3 * raster_width * raster_height; }
+ inline uint8_t *get_raster() { return raster; }
+
+ bool decompress_jpeg_buf(char *data, uint32_t data_len)
+ {
+ ros_jpeg_mutex_lock();
+ jpeg_buffer_src(&dinfo, data, data_len);
+ jpeg_read_header(&dinfo, TRUE);
+ jpeg_start_decompress(&dinfo);
+ if (dinfo.output_components != 3)
+ {
+ printf("woah! this jpeg buffer doesn't have three components.\n");
+ return false;
+ }
+ raster_width = dinfo.output_width;
+ raster_height = dinfo.output_height;
+ realloc_raster_if_needed();
+ int row_stride = raster_width * 3;
+ JSAMPROW row_pointer[1];
+ while (dinfo.output_scanline < dinfo.output_height)
+ {
+ row_pointer[0] = (JSAMPROW)&raster[dinfo.output_scanline * row_stride];
+ jpeg_read_scanlines(&dinfo, row_pointer, 1);
+ }
+ jpeg_finish_decompress(&dinfo);
+ ros_jpeg_mutex_unlock();
+ return true;
+ }
+protected:
+ uint8_t *raster;
+ int raster_width, raster_height;
+ int raster_alloc_size;
+ jpeg_compress_struct cinfo;
+ jpeg_decompress_struct dinfo;
+ jpeg_error_mgr jerr;
+
+ static void buffer_dest_init(j_compress_ptr cinfo) { }
+ static void buffer_source_init(j_decompress_ptr cinfo) { }
+ static boolean buffer_source_fill(j_decompress_ptr dinfo)
+ {
+ if (dinfo->src->bytes_in_buffer == 0)
+ {
+ printf("woah! jpeg memory buffer was incomplete! ahhhh\n");
+ return FALSE;
+ }
+ return TRUE;
+ }
+ static void buffer_source_skip(j_decompress_ptr dinfo, long num_bytes)
+ {
+ dinfo->src->next_input_byte += (size_t)num_bytes;
+ dinfo->src->bytes_in_buffer -= (size_t)num_bytes;
+ }
+ static void buffer_source_term(j_decompress_ptr dinfo) { }
+ static boolean buffer_dest_empty(j_compress_ptr cinfo)
+ {
+ // TODO: enlarge the compression buffer by a factor of 2 and
+ // copy over everything, then reset the write pointer
+ // and the number of available bytes
+ }
+ static void buffer_dest_term(j_compress_ptr cinfo) { }
+ static void jpeg_buffer_src(j_decompress_ptr dinfo, char *buf, int size)
+ {
+ if (dinfo->src == NULL)
+ dinfo->src = (struct jpeg_source_mgr *)(*dinfo->mem->alloc_small)
+ ((j_common_ptr)dinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr));
+ dinfo->src->init_source = buffer_source_init;
+ dinfo->src->fill_input_buffer = buffer_source_fill;
+ dinfo->src->skip_input_data = buffer_source_skip;
+ dinfo->src->resync_to_restart = jpeg_resync_to_restart;
+ dinfo->src->next_input_byte = (JOCTET *)buf;
+ dinfo->src->bytes_in_buffer = size;
+ dinfo->src->term_source = buffer_source_term;
+ }
+ static void jpeg_buffer_dest(j_compress_ptr cinfo, char *buf, int size)
+ {
+ // TODO
+ }
+
+ void realloc_raster_if_needed()
+ {
+ if (raster_alloc_size < raster_size())
+ {
+ if (raster)
+ delete[] raster;
+ raster_alloc_size = raster_size();
+ if (raster_alloc_size)
+ raster = new uint8_t[raster_alloc_size];
+ else
+ raster = NULL;
+ }
+ }
+};
+
+
+#endif
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mor...@us...> - 2008-04-11 17:55:41
|
Revision: 99
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=99&view=rev
Author: morgan_quigley
Date: 2008-04-11 10:55:41 -0700 (Fri, 11 Apr 2008)
Log Message:
-----------
a ppm-writing class and a simple checkerboard generator program
Added Paths:
-----------
pkg/trunk/image_utils/include/image_utils/ppm_wrapper.h
pkg/trunk/image_utils/src/
pkg/trunk/image_utils/src/create_chessboard/
pkg/trunk/image_utils/src/create_chessboard/Makefile
pkg/trunk/image_utils/src/create_chessboard/create_chessboard.cpp
pkg/trunk/image_utils/test/ppm/
pkg/trunk/image_utils/test/ppm/Makefile
pkg/trunk/image_utils/test/ppm/ppm.cpp
Added: pkg/trunk/image_utils/include/image_utils/ppm_wrapper.h
===================================================================
--- pkg/trunk/image_utils/include/image_utils/ppm_wrapper.h (rev 0)
+++ pkg/trunk/image_utils/include/image_utils/ppm_wrapper.h 2008-04-11 17:55:41 UTC (rev 99)
@@ -0,0 +1,48 @@
+#ifndef IMAGE_UTILS_PPM_WRAPPER_H
+#define IMAGE_UTILS_PPM_WRAPPER_H
+
+// this guy encapsulates reading / writing ppm images
+#include <string>
+#include <cstdio>
+#include <cassert>
+using std::string;
+
+class PpmWrapper
+{
+public:
+ PpmWrapper();
+ ~PpmWrapper();
+
+ static char *write_file(string filename, int width, int height,
+ string colorspace, uint8_t *raster)
+ {
+ if (colorspace != string("rgb24") && colorspace != string("bgr24"))
+ return "woah! PpmWrapper can only handle rgb24 or bgr24 images";
+ FILE *f = fopen(filename.c_str(), "wb");
+ if (!f)
+ return "couldn't open file to write ppm";
+ fprintf(f, "P6%d %d\n255\n", width, height);
+ if (colorspace == string("rgb24"))
+ fwrite(raster, 1, width*height*3, f);
+ else if (colorspace == string("bgr24"))
+ {
+ uint8_t *bgr = new uint8_t[width*height*3];
+ for (int y = 0; y < height; y++)
+ for(int x = 0; x < height; x++)
+ {
+ uint8_t *p = raster + y * width * 3 + x * 3;
+ uint8_t *q = bgr + y * width * 3 + x * 3;
+ q[0] = p[2]; q[1] = p[1]; q[2] = p[0];
+ }
+ fwrite(bgr, 1, width * height * 3, f);
+ delete[] bgr;
+ }
+ else
+ assert(0);
+ fclose(f);
+ return NULL; // no error
+ }
+};
+
+#endif
+
Added: pkg/trunk/image_utils/src/create_chessboard/Makefile
===================================================================
--- pkg/trunk/image_utils/src/create_chessboard/Makefile (rev 0)
+++ pkg/trunk/image_utils/src/create_chessboard/Makefile 2008-04-11 17:55:41 UTC (rev 99)
@@ -0,0 +1,4 @@
+SRC = create_chessboard.cpp
+OUT = create_chessboard
+PKG = image_utils
+include $(shell $(ROS_ROOT)/rospack find roscpp)/make_include/node.mk
Added: pkg/trunk/image_utils/src/create_chessboard/create_chessboard.cpp
===================================================================
--- pkg/trunk/image_utils/src/create_chessboard/create_chessboard.cpp (rev 0)
+++ pkg/trunk/image_utils/src/create_chessboard/create_chessboard.cpp 2008-04-11 17:55:41 UTC (rev 99)
@@ -0,0 +1,36 @@
+#include "image_utils/ppm_wrapper.h"
+#include <cstdio>
+
+int main(int argc, char **argv)
+{
+ if (argc < 3)
+ {
+ printf("usage: create_chessboard WIDTH HEIGHT [SIZE]\n");
+ printf(" where WIDTH, HEIGHT are the number of square, and\n");
+ printf(" SIZE is the pixel length of the side of each square.\n");
+ return 1;
+ }
+
+ int w = atoi(argv[1]), h = atoi(argv[2]);
+ int s = 200;
+ if (argc >= 4)
+ s = atoi(argv[3]);
+ printf("creating %d by %d board with %d-pixel squares\n", w, h, s);
+
+ int img_width = w*s, img_height = h*s;
+ uint8_t *img = new uint8_t[img_width*img_height*3];
+ for (int y = 0; y < img_height; y++)
+ for (int x = 0; x < img_width; x++)
+ {
+ uint8_t *p = img + y * img_width * 3 + x * 3;
+ uint8_t xc = (uint8_t)(x / s) % 2;
+ uint8_t yc = (uint8_t)(y / s) % 2;
+ uint8_t c = (xc ^ yc ? 255 : 0);
+ p[0] = p[1] = p[2] = c;
+ }
+
+ PpmWrapper::write_file("board.ppm", img_width, img_height, "rgb24", img);
+ delete[] img;
+
+ return 0;
+}
Added: pkg/trunk/image_utils/test/ppm/Makefile
===================================================================
--- pkg/trunk/image_utils/test/ppm/Makefile (rev 0)
+++ pkg/trunk/image_utils/test/ppm/Makefile 2008-04-11 17:55:41 UTC (rev 99)
@@ -0,0 +1,4 @@
+SRC = ppm.cpp
+OUT = ppm
+PKG = image_utils
+include $(shell $(ROS_ROOT)/rospack find roscpp)/make_include/node.mk
Added: pkg/trunk/image_utils/test/ppm/ppm.cpp
===================================================================
--- pkg/trunk/image_utils/test/ppm/ppm.cpp (rev 0)
+++ pkg/trunk/image_utils/test/ppm/ppm.cpp 2008-04-11 17:55:41 UTC (rev 99)
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+// The image_flows package provides image transport, codec wrapping, and
+// various handy image utilities.
+//
+// Copyright (C) 2008, Morgan Quigley
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of Stanford University nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+
+#include "image_utils/ppm_wrapper.h"
+
+int main(int argc, char **argv)
+{
+ int width = 640, height = 480;
+ uint8_t *raster = new uint8_t[width*height*3];
+ for (int y = 0; y < height; y++)
+ for (int x = 0; x < width; x++)
+ {
+ raster[y*width*3 + x*3 ] = rand() % 255;
+ raster[y*width*3 + x*3 + 1] = rand() % 255;
+ raster[y*width*3 + x*3 + 2] = rand() % 255;
+ }
+ PpmWrapper::write_file("test.ppm", width, height, "rgb24", raster);
+
+ return 0;
+}
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|