aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp
new file mode 100644
index 0000000..944db6c
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CImageWriterJPG.cpp
@@ -0,0 +1,229 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CImageWriterJPG.h"
6
7#ifdef _IRR_COMPILE_WITH_JPG_WRITER_
8
9#include "CColorConverter.h"
10#include "IWriteFile.h"
11#include "CImage.h"
12#include "irrString.h"
13
14#ifdef _IRR_COMPILE_WITH_LIBJPEG_
15#include <stdio.h> // required for jpeglib.h
16extern "C"
17{
18#ifndef _IRR_USE_NON_SYSTEM_JPEG_LIB_
19 #include <jpeglib.h>
20 #include <jerror.h>
21#else
22 #include "jpeglib/jpeglib.h"
23 #include "jpeglib/jerror.h"
24#endif
25}
26
27
28namespace irr
29{
30namespace video
31{
32
33// The writer uses a 4k buffer and flushes to disk each time it's filled
34#define OUTPUT_BUF_SIZE 4096
35typedef struct
36{
37 struct jpeg_destination_mgr pub;/* public fields */
38
39 io::IWriteFile* file; /* target file */
40 JOCTET buffer[OUTPUT_BUF_SIZE]; /* image buffer */
41} mem_destination_mgr;
42
43
44typedef mem_destination_mgr * mem_dest_ptr;
45
46
47// init
48static void jpeg_init_destination(j_compress_ptr cinfo)
49{
50 mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
51 dest->pub.next_output_byte = dest->buffer;
52 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
53}
54
55
56// flush to disk and reset buffer
57static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
58{
59 mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
60
61 // for now just exit upon file error
62 if (dest->file->write(dest->buffer, OUTPUT_BUF_SIZE) != OUTPUT_BUF_SIZE)
63 ERREXIT (cinfo, JERR_FILE_WRITE);
64
65 dest->pub.next_output_byte = dest->buffer;
66 dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
67
68 return TRUE;
69}
70
71
72static void jpeg_term_destination(j_compress_ptr cinfo)
73{
74 mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest;
75 const s32 datacount = (s32)(OUTPUT_BUF_SIZE - dest->pub.free_in_buffer);
76 // for now just exit upon file error
77 if (dest->file->write(dest->buffer, datacount) != datacount)
78 ERREXIT (cinfo, JERR_FILE_WRITE);
79}
80
81
82// set up buffer data
83static void jpeg_file_dest(j_compress_ptr cinfo, io::IWriteFile* file)
84{
85 if (cinfo->dest == NULL)
86 { /* first time for this JPEG object? */
87 cinfo->dest = (struct jpeg_destination_mgr *)
88 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
89 JPOOL_PERMANENT,
90 sizeof(mem_destination_mgr));
91 }
92
93 mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; /* for casting */
94
95 /* Initialize method pointers */
96 dest->pub.init_destination = jpeg_init_destination;
97 dest->pub.empty_output_buffer = jpeg_empty_output_buffer;
98 dest->pub.term_destination = jpeg_term_destination;
99
100 /* Initialize private member */
101 dest->file = file;
102}
103
104
105/* write_JPEG_memory: store JPEG compressed image into memory.
106*/
107static bool writeJPEGFile(io::IWriteFile* file, IImage* image, u32 quality)
108{
109 void (*format)(const void*, s32, void*) = 0;
110 switch( image->getColorFormat () )
111 {
112 case ECF_R8G8B8:
113 format = CColorConverter::convert_R8G8B8toR8G8B8;
114 break;
115 case ECF_A8R8G8B8:
116 format = CColorConverter::convert_A8R8G8B8toR8G8B8;
117 break;
118 case ECF_A1R5G5B5:
119 format = CColorConverter::convert_A1R5G5B5toB8G8R8;
120 break;
121 case ECF_R5G6B5:
122 format = CColorConverter::convert_R5G6B5toR8G8B8;
123 break;
124#ifndef _DEBUG
125 default:
126 break;
127#endif
128 }
129
130 // couldn't find a color converter
131 if ( 0 == format )
132 return false;
133
134 const core::dimension2du dim = image->getDimension();
135
136 struct jpeg_compress_struct cinfo;
137 struct jpeg_error_mgr jerr;
138 cinfo.err = jpeg_std_error(&jerr);
139
140 jpeg_create_compress(&cinfo);
141 jpeg_file_dest(&cinfo, file);
142 cinfo.image_width = dim.Width;
143 cinfo.image_height = dim.Height;
144 cinfo.input_components = 3;
145 cinfo.in_color_space = JCS_RGB;
146
147 jpeg_set_defaults(&cinfo);
148
149 if ( 0 == quality )
150 quality = 75;
151
152 jpeg_set_quality(&cinfo, quality, TRUE);
153 jpeg_start_compress(&cinfo, TRUE);
154
155 u8 * dest = new u8[dim.Width*3];
156
157 if (dest)
158 {
159 const u32 pitch = image->getPitch();
160 JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
161 row_pointer[0] = dest;
162
163 u8* src = (u8*)image->lock();
164
165 while (cinfo.next_scanline < cinfo.image_height)
166 {
167 // convert next line
168 format( src, dim.Width, dest );
169 src += pitch;
170 jpeg_write_scanlines(&cinfo, row_pointer, 1);
171 }
172 image->unlock();
173
174 delete [] dest;
175
176 /* Step 6: Finish compression */
177 jpeg_finish_compress(&cinfo);
178 }
179
180 /* Step 7: Destroy */
181 jpeg_destroy_compress(&cinfo);
182
183 return (dest != 0);
184}
185
186
187} // namespace video
188} // namespace irr
189
190#endif // _IRR_COMPILE_WITH_LIBJPEG_
191
192namespace irr
193{
194namespace video
195{
196
197IImageWriter* createImageWriterJPG()
198{
199 return new CImageWriterJPG;
200}
201
202CImageWriterJPG::CImageWriterJPG()
203{
204#ifdef _DEBUG
205 setDebugName("CImageWriterJPG");
206#endif
207}
208
209
210bool CImageWriterJPG::isAWriteableFileExtension(const io::path& filename) const
211{
212 return core::hasFileExtension ( filename, "jpg", "jpeg" );
213}
214
215
216bool CImageWriterJPG::writeImage(io::IWriteFile *file, IImage *image, u32 quality) const
217{
218#ifndef _IRR_COMPILE_WITH_LIBJPEG_
219 return false;
220#else
221 return writeJPEGFile(file, image, quality);
222#endif
223}
224
225} // namespace video
226} // namespace irr
227
228#endif
229