merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / filter.vcl / jpeg / jpegc.c
blobe7a78c27b62a67a04ab8d5b56ecd56dad054611c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: jpegc.c,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include "setjmp.h"
34 #include "jpeglib.h"
35 #include "jerror.h"
36 #include "jpeg.h"
37 #include "rtl/alloc.h"
38 #include "osl/diagnose.h"
40 struct my_error_mgr
42 struct jpeg_error_mgr pub;
43 jmp_buf setjmp_buffer;
46 void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile);
47 void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile);
49 METHODDEF( void )
50 my_error_exit (j_common_ptr cinfo)
52 my_error_ptr myerr = (my_error_ptr) cinfo->err;
53 (*cinfo->err->output_message) (cinfo);
54 longjmp(myerr->setjmp_buffer, 1);
58 METHODDEF( void )
59 my_output_message (j_common_ptr cinfo)
61 char buffer[JMSG_LENGTH_MAX];
62 (*cinfo->err->format_message) (cinfo, buffer);
65 /* TODO: when incompatible changes are possible again
66 the preview size hint should be redone */
67 static int nPreviewWidth = 0;
68 static int nPreviewHeight = 0;
69 void SetJpegPreviewSizeHint( int nWidth, int nHeight )
71 nPreviewWidth = nWidth;
72 nPreviewHeight = nHeight;
75 void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
77 struct jpeg_decompress_struct cinfo;
78 struct my_error_mgr jerr;
79 struct JPEGCreateBitmapParam aCreateBitmapParam;
80 HPBYTE pDIB;
81 HPBYTE pTmp;
82 long nWidth;
83 long nHeight;
84 long nAlignedWidth;
85 JSAMPLE * range_limit;
86 HPBYTE pScanLineBuffer = NULL;
87 long nScanLineBufferComponents = 0;
88 // declare bDecompCreated volatile because of gcc
89 // warning: variable 'bDecompCreated' might be clobbered by `longjmp' or `vfork'
90 volatile long bDecompCreated = 0;
92 /* Falls der Stream nicht ausreicht (IO_PENDING)
93 wird ueber ein longjmp in der Schleife nach Exit
94 gesprungen, wir geben dann die Anzahl
95 der bisher bearbeiteten Scanlines zurueck*/
96 if ( setjmp( jerr.setjmp_buffer ) )
97 goto Exit;
99 cinfo.err = jpeg_std_error( &jerr.pub );
100 jerr.pub.error_exit = my_error_exit;
101 jerr.pub.output_message = my_output_message;
103 jpeg_create_decompress( &cinfo );
104 bDecompCreated = 1;
105 jpeg_svstream_src( &cinfo, pIStm );
106 jpeg_read_header( &cinfo, TRUE );
108 cinfo.scale_num = 1;
109 cinfo.scale_denom = 1;
110 cinfo.output_gamma = 1.0;
111 cinfo.raw_data_out = FALSE;
112 cinfo.quantize_colors = FALSE;
113 if ( cinfo.jpeg_color_space == JCS_YCbCr )
114 cinfo.out_color_space = JCS_RGB;
115 else if ( cinfo.jpeg_color_space == JCS_YCCK )
116 cinfo.out_color_space = JCS_CMYK;
118 OSL_ASSERT(cinfo.out_color_space == JCS_CMYK || cinfo.out_color_space == JCS_GRAYSCALE || cinfo.out_color_space == JCS_RGB);
120 /* change scale for preview import */
121 if( nPreviewWidth || nPreviewHeight )
123 if( nPreviewWidth == 0 ) {
124 nPreviewWidth = ( cinfo.image_width*nPreviewHeight )/cinfo.image_height;
125 if( nPreviewWidth <= 0 )
126 nPreviewWidth = 1;
127 } else if( nPreviewHeight == 0 ) {
128 nPreviewHeight = ( cinfo.image_height*nPreviewWidth )/cinfo.image_width;
129 if( nPreviewHeight <= 0 )
130 nPreviewHeight = 1;
133 for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
135 if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
136 break;
137 if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
138 break;
141 if( cinfo.scale_denom > 1 )
143 cinfo.dct_method = JDCT_FASTEST;
144 cinfo.do_fancy_upsampling = FALSE;
145 cinfo.do_block_smoothing = FALSE;
149 jpeg_start_decompress( &cinfo );
151 nWidth = cinfo.output_width;
152 nHeight = cinfo.output_height;
153 aCreateBitmapParam.nWidth = nWidth;
154 aCreateBitmapParam.nHeight = nHeight;
156 aCreateBitmapParam.density_unit = cinfo.density_unit;
157 aCreateBitmapParam.X_density = cinfo.X_density;
158 aCreateBitmapParam.Y_density = cinfo.Y_density;
159 aCreateBitmapParam.bGray = cinfo.output_components == 1;
160 pDIB = CreateBitmap( pJPEGReader, &aCreateBitmapParam );
161 nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
162 range_limit=cinfo.sample_range_limit;
164 if ( cinfo.out_color_space == JCS_CMYK )
166 nScanLineBufferComponents = cinfo.output_width * 4;
167 pScanLineBuffer = rtl_allocateMemory( nScanLineBufferComponents );
170 if( pDIB )
172 if( aCreateBitmapParam.bTopDown )
173 pTmp = pDIB;
174 else
176 pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
177 nAlignedWidth = -nAlignedWidth;
180 for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
182 if (pScanLineBuffer!=NULL) { // in other words cinfo.out_color_space == JCS_CMYK
183 int i;
184 int j;
185 jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
186 // convert CMYK to RGB
187 for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
189 int c_=255-pScanLineBuffer[i+0];
190 int m_=255-pScanLineBuffer[i+1];
191 int y_=255-pScanLineBuffer[i+2];
192 int k_=255-pScanLineBuffer[i+3];
193 pTmp[j+0]=range_limit[ 255L - ( c_ + k_ ) ];
194 pTmp[j+1]=range_limit[ 255L - ( m_ + k_ ) ];
195 pTmp[j+2]=range_limit[ 255L - ( y_ + k_ ) ];
197 } else {
198 jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
200 /* PENDING ??? */
201 if ( cinfo.err->msg_code == 113 )
202 break;
204 pTmp += nAlignedWidth;
208 jpeg_finish_decompress( &cinfo );
209 if (pScanLineBuffer!=NULL) {
210 rtl_freeMemory( pScanLineBuffer );
211 pScanLineBuffer=NULL;
214 Exit:
216 if( bDecompCreated )
217 jpeg_destroy_decompress( &cinfo );
220 long WriteJPEG( void* pJPEGWriter, void* pOStm,
221 long nWidth, long nHeight,
222 long nQualityPercent, void* pCallbackData )
224 struct jpeg_compress_struct cinfo;
225 struct my_error_mgr jerr;
226 void* pScanline;
227 long nY;
228 // declare bCompCreated, bRet volatile because of gcc
229 // warning: variable 'bCompCreated' might be clobbered by `longjmp' or `vfork'
230 volatile long bCompCreated = 0;
231 volatile long bRet = 0;
233 if ( setjmp( jerr.setjmp_buffer ) )
234 goto Exit;
236 cinfo.err = jpeg_std_error( &jerr.pub );
237 jerr.pub.error_exit = my_error_exit;
238 jerr.pub.output_message = my_output_message;
240 jpeg_create_compress( &cinfo );
241 bCompCreated = 1;
243 jpeg_svstream_dest( &cinfo, pOStm );
245 cinfo.image_width = (JDIMENSION) nWidth;
246 cinfo.image_height = (JDIMENSION) nHeight;
247 cinfo.input_components = 3;
248 cinfo.in_color_space = JCS_RGB;
250 jpeg_set_defaults( &cinfo );
251 jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE );
253 if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
254 jpeg_simple_progression( &cinfo );
256 jpeg_start_compress( &cinfo, TRUE );
258 for( nY = 0; nY < nHeight; nY++ )
260 pScanline = GetScanline( pJPEGWriter, nY );
262 if( pScanline )
263 jpeg_write_scanlines( &cinfo, (JSAMPARRAY) &pScanline, 1 );
265 if( JPEGCallback( pCallbackData, nY * 100L / nHeight ) )
266 goto Exit;
269 bRet = 1;
271 jpeg_finish_compress(&cinfo);
273 Exit:
275 if ( bCompCreated )
276 jpeg_destroy_compress( &cinfo );
278 return bRet;