root/trunk/include/mapnik/jpeg_io.hpp

Revision 1829, 4.0 kB (checked in by dane, 8 weeks ago)

scons: make libjpeg dependency optional (still required by default)

Line 
1/*****************************************************************************
2 *
3 * This file is part of Mapnik (c++ mapping toolkit)
4 *
5 * Copyright (C) 2006 Artem Pavlenko
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 *****************************************************************************/
22
23//$Id$
24#if defined(HAVE_JPEG)
25
26#include <mapnik/global.hpp>
27
28extern "C"
29{
30#include <jpeglib.h>
31}
32
33namespace mapnik {
34
35#define BUFFER_SIZE 4096
36   
37typedef struct 
38{
39    struct jpeg_destination_mgr pub;
40    std::ostream * out;
41    JOCTET * buffer;
42} dest_mgr;
43   
44inline void init_destination( j_compress_ptr cinfo)
45{
46    dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
47    dest->buffer = (JOCTET*) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
48                                                         BUFFER_SIZE * sizeof(JOCTET));
49    dest->pub.next_output_byte = dest->buffer;
50    dest->pub.free_in_buffer = BUFFER_SIZE;
51}
52
53inline boolean empty_output_buffer (j_compress_ptr cinfo)
54{
55    dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
56    dest->out->write((char*)dest->buffer, BUFFER_SIZE);
57    if (!*(dest->out)) return false;
58    dest->pub.next_output_byte = dest->buffer;
59    dest->pub.free_in_buffer = BUFFER_SIZE;
60    return true;
61}
62   
63inline void term_destination( j_compress_ptr cinfo)
64{
65    dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
66    size_t size  = BUFFER_SIZE - dest->pub.free_in_buffer;
67    if (size > 0) 
68    {
69        dest->out->write((char*)dest->buffer, size);
70    }
71    dest->out->flush();
72}
73   
74template <typename T1, typename T2>
75void save_as_jpeg(T1 & file,int quality, T2 const& image)
76{ 
77    struct jpeg_compress_struct cinfo;
78    struct jpeg_error_mgr jerr;
79
80    int width=image.width();
81    int height=image.height();
82       
83    cinfo.err = jpeg_std_error(&jerr);
84    jpeg_create_compress(&cinfo);
85   
86    cinfo.dest = (struct jpeg_destination_mgr *)(*cinfo.mem->alloc_small)
87        ((j_common_ptr) &cinfo, JPOOL_PERMANENT, sizeof(dest_mgr));
88    dest_mgr * dest = (dest_mgr*) cinfo.dest;
89    dest->pub.init_destination = init_destination;
90    dest->pub.empty_output_buffer = empty_output_buffer;
91    dest->pub.term_destination = term_destination;
92    dest->out = &file;
93     
94    //jpeg_stdio_dest(&cinfo, fp);
95    cinfo.image_width = width;
96    cinfo.image_height = height;
97    cinfo.input_components = 3;
98    cinfo.in_color_space = JCS_RGB; 
99    jpeg_set_defaults(&cinfo);
100    jpeg_set_quality(&cinfo, quality,1);
101    jpeg_start_compress(&cinfo, 1);
102    JSAMPROW row_pointer[1];
103    JSAMPLE* row=reinterpret_cast<JSAMPLE*>( ::operator new (sizeof(JSAMPLE) * width*3));
104    while (cinfo.next_scanline < cinfo.image_height) 
105    {
106        const unsigned* imageRow=image.getRow(cinfo.next_scanline);
107        int index=0;
108        for (int i=0;i<width;++i)
109        {
110#ifdef MAPNIK_BIG_ENDIAN
111            row[index++]=(imageRow[i]>>24)&0xff;
112            row[index++]=(imageRow[i]>>16)&0xff;
113            row[index++]=(imageRow[i]>>8)&0xff;
114#else
115            row[index++]=(imageRow[i])&0xff;
116            row[index++]=(imageRow[i]>>8)&0xff;
117            row[index++]=(imageRow[i]>>16)&0xff;
118#endif
119        }
120        row_pointer[0] = &row[0];
121        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
122    }
123    ::operator delete(row);
124     
125    jpeg_finish_compress(&cinfo);
126    jpeg_destroy_compress(&cinfo);
127} 
128}
129
130#endif
Note: See TracBrowser for help on using the browser.