masterfix DEV300: #i10000# removeing moved code
This commit is contained in:
parent
4296c7c855
commit
87987da3c2
2 changed files with 0 additions and 1061 deletions
|
@ -1,777 +0,0 @@
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
||||||
*
|
|
||||||
* OpenOffice.org - a multi-platform office productivity suite
|
|
||||||
*
|
|
||||||
* This file is part of OpenOffice.org.
|
|
||||||
*
|
|
||||||
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License version 3
|
|
||||||
* only, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License version 3 for more details
|
|
||||||
* (a copy is included in the LICENSE file that accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* version 3 along with OpenOffice.org. If not, see
|
|
||||||
* <http://www.openoffice.org/license.html>
|
|
||||||
* for a copy of the LGPLv3 License.
|
|
||||||
*
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
||||||
#include "precompiled_svtools.hxx"
|
|
||||||
|
|
||||||
#include <tools/solar.h>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "jpeg.h"
|
|
||||||
#include "jpeg/jpeglib.h"
|
|
||||||
#include "jpeg/jerror.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
#define _JPEGPRIVATE
|
|
||||||
#include <vcl/bmpacc.hxx>
|
|
||||||
#include "jpeg.hxx"
|
|
||||||
#include <svtools/FilterConfigItem.hxx>
|
|
||||||
#include <svtools/filter.hxx>
|
|
||||||
|
|
||||||
// -----------
|
|
||||||
// - Defines -
|
|
||||||
// -----------
|
|
||||||
|
|
||||||
using namespace ::com::sun::star;
|
|
||||||
|
|
||||||
#define JPEGMINREAD 512
|
|
||||||
|
|
||||||
// -------------
|
|
||||||
// - (C-Calls) -
|
|
||||||
// -------------
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
extern "C" void* CreateBitmap( void* pJPEGReader, void* pJPEGCreateBitmapParam )
|
|
||||||
{
|
|
||||||
return ( (JPEGReader*) pJPEGReader )->CreateBitmap( pJPEGCreateBitmapParam );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
extern "C" void* GetScanline( void* pJPEGWriter, long nY )
|
|
||||||
{
|
|
||||||
return ( (JPEGWriter*) pJPEGWriter )->GetScanline( nY );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct JPEGCallbackStruct
|
|
||||||
{
|
|
||||||
uno::Reference< task::XStatusIndicator > xStatusIndicator;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" long JPEGCallback( void* pCallbackData, long nPercent )
|
|
||||||
{
|
|
||||||
JPEGCallbackStruct* pS = (JPEGCallbackStruct*)pCallbackData;
|
|
||||||
if ( pS && pS->xStatusIndicator.is() )
|
|
||||||
{
|
|
||||||
pS->xStatusIndicator->setValue( nPercent );
|
|
||||||
}
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUF_SIZE 4096
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
struct jpeg_destination_mgr pub; /* public fields */
|
|
||||||
|
|
||||||
SvStream* outfile; /* target stream */
|
|
||||||
JOCTET * buffer; /* start of buffer */
|
|
||||||
} my_destination_mgr;
|
|
||||||
|
|
||||||
typedef my_destination_mgr * my_dest_ptr;
|
|
||||||
|
|
||||||
extern "C" void init_destination (j_compress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
|
||||||
|
|
||||||
/* Allocate the output buffer --- it will be released when done with image */
|
|
||||||
dest->buffer = (JOCTET *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
|
||||||
BUF_SIZE * sizeof(JOCTET));
|
|
||||||
|
|
||||||
dest->pub.next_output_byte = dest->buffer;
|
|
||||||
dest->pub.free_in_buffer = BUF_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int empty_output_buffer (j_compress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
|
||||||
|
|
||||||
if (dest->outfile->Write(dest->buffer, BUF_SIZE) !=
|
|
||||||
(size_t) BUF_SIZE)
|
|
||||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
|
||||||
|
|
||||||
dest->pub.next_output_byte = dest->buffer;
|
|
||||||
dest->pub.free_in_buffer = BUF_SIZE;
|
|
||||||
|
|
||||||
return sal_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void term_destination (j_compress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
|
||||||
size_t datacount = BUF_SIZE - dest->pub.free_in_buffer;
|
|
||||||
|
|
||||||
/* Write any data remaining in the buffer */
|
|
||||||
if (datacount > 0) {
|
|
||||||
if (dest->outfile->Write(dest->buffer, datacount) != datacount)
|
|
||||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void jpeg_svstream_dest (j_compress_ptr cinfo, void* out)
|
|
||||||
{
|
|
||||||
SvStream * outfile = (SvStream*)out;
|
|
||||||
my_dest_ptr dest;
|
|
||||||
|
|
||||||
/* The destination object is made permanent so that multiple JPEG images
|
|
||||||
* can be written to the same file without re-executing jpeg_svstream_dest.
|
|
||||||
* This makes it dangerous to use this manager and a different destination
|
|
||||||
* manager serially with the same JPEG object, because their private object
|
|
||||||
* sizes may be different. Caveat programmer.
|
|
||||||
*/
|
|
||||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
|
||||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
sizeof(my_destination_mgr));
|
|
||||||
}
|
|
||||||
|
|
||||||
dest = (my_dest_ptr) cinfo->dest;
|
|
||||||
dest->pub.init_destination = init_destination;
|
|
||||||
dest->pub.empty_output_buffer = empty_output_buffer;
|
|
||||||
dest->pub.term_destination = term_destination;
|
|
||||||
dest->outfile = outfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expanded data source object for stdio input */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct jpeg_source_mgr pub; /* public fields */
|
|
||||||
|
|
||||||
SvStream * infile; /* source stream */
|
|
||||||
JOCTET * buffer; /* start of buffer */
|
|
||||||
boolean start_of_file; /* have we gotten any data yet? */
|
|
||||||
} my_source_mgr;
|
|
||||||
|
|
||||||
typedef my_source_mgr * my_src_ptr;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize source --- called by jpeg_read_header
|
|
||||||
* before any data is actually read.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C" void init_source (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
||||||
|
|
||||||
/* We reset the empty-input-file flag for each image,
|
|
||||||
* but we don't clear the input buffer.
|
|
||||||
* This is correct behavior for reading a series of images from one source.
|
|
||||||
*/
|
|
||||||
src->start_of_file = sal_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
long StreamRead( SvStream* pSvStm, void* pBuffer, long nBufferSize )
|
|
||||||
{
|
|
||||||
long nRead;
|
|
||||||
|
|
||||||
if( pSvStm->GetError() != ERRCODE_IO_PENDING )
|
|
||||||
{
|
|
||||||
long nActPos = pSvStm->Tell();
|
|
||||||
|
|
||||||
nRead = (long) pSvStm->Read( pBuffer, nBufferSize );
|
|
||||||
|
|
||||||
if( pSvStm->GetError() == ERRCODE_IO_PENDING )
|
|
||||||
{
|
|
||||||
nRead = 0;
|
|
||||||
|
|
||||||
// Damit wir wieder an die alte Position
|
|
||||||
// seeken koennen, setzen wir den Error temp.zurueck
|
|
||||||
pSvStm->ResetError();
|
|
||||||
pSvStm->Seek( nActPos );
|
|
||||||
pSvStm->SetError( ERRCODE_IO_PENDING );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nRead = 0;
|
|
||||||
|
|
||||||
return nRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int fill_input_buffer (j_decompress_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
||||||
size_t nbytes;
|
|
||||||
|
|
||||||
nbytes = StreamRead(src->infile, src->buffer, BUF_SIZE);
|
|
||||||
|
|
||||||
if (nbytes <= 0) {
|
|
||||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
|
||||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
|
||||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
|
||||||
/* Insert a fake EOI marker */
|
|
||||||
src->buffer[0] = (JOCTET) 0xFF;
|
|
||||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
|
||||||
nbytes = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
src->pub.next_input_byte = src->buffer;
|
|
||||||
src->pub.bytes_in_buffer = nbytes;
|
|
||||||
src->start_of_file = sal_False;
|
|
||||||
|
|
||||||
return sal_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
|
||||||
{
|
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
||||||
|
|
||||||
/* Just a dumb implementation for now. Could use fseek() except
|
|
||||||
* it doesn't work on pipes. Not clear that being smart is worth
|
|
||||||
* any trouble anyway --- large skips are infrequent.
|
|
||||||
*/
|
|
||||||
if (num_bytes > 0) {
|
|
||||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
|
||||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
|
||||||
(void) fill_input_buffer(cinfo);
|
|
||||||
/* note we assume that fill_input_buffer will never return sal_False,
|
|
||||||
* so suspension need not be handled.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
src->pub.next_input_byte += (size_t) num_bytes;
|
|
||||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void term_source (j_decompress_ptr)
|
|
||||||
{
|
|
||||||
/* no work necessary here */
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void jpeg_svstream_src (j_decompress_ptr cinfo, void * in)
|
|
||||||
{
|
|
||||||
my_src_ptr src;
|
|
||||||
SvStream * infile = (SvStream*)in;
|
|
||||||
|
|
||||||
/* The source object and input buffer are made permanent so that a series
|
|
||||||
* of JPEG images can be read from the same file by calling jpeg_stdio_src
|
|
||||||
* only before the first one. (If we discarded the buffer at the end of
|
|
||||||
* one image, we'd likely lose the start of the next one.)
|
|
||||||
* This makes it unsafe to use this manager and a different source
|
|
||||||
* manager serially with the same JPEG object. Caveat programmer.
|
|
||||||
*/
|
|
||||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
|
||||||
cinfo->src = (struct jpeg_source_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
sizeof(my_source_mgr));
|
|
||||||
src = (my_src_ptr) cinfo->src;
|
|
||||||
src->buffer = (JOCTET *)
|
|
||||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
BUF_SIZE * sizeof(JOCTET));
|
|
||||||
}
|
|
||||||
|
|
||||||
src = (my_src_ptr) cinfo->src;
|
|
||||||
src->pub.init_source = init_source;
|
|
||||||
src->pub.fill_input_buffer = fill_input_buffer;
|
|
||||||
src->pub.skip_input_data = skip_input_data;
|
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
|
||||||
src->pub.term_source = term_source;
|
|
||||||
src->infile = infile;
|
|
||||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
|
||||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// - JPEGReader -
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
JPEGReader::JPEGReader( SvStream& rStm, void* /*pCallData*/, sal_Bool bSetLS ) :
|
|
||||||
rIStm ( rStm ),
|
|
||||||
pAcc ( NULL ),
|
|
||||||
pAcc1 ( NULL ),
|
|
||||||
pBuffer ( NULL ),
|
|
||||||
nLastPos ( rStm.Tell() ),
|
|
||||||
nLastLines ( 0 ),
|
|
||||||
bSetLogSize ( bSetLS )
|
|
||||||
{
|
|
||||||
maUpperName = String::CreateFromAscii( "SVIJPEG", 7 );
|
|
||||||
nFormerPos = nLastPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
JPEGReader::~JPEGReader()
|
|
||||||
{
|
|
||||||
if( pBuffer )
|
|
||||||
rtl_freeMemory( pBuffer );
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
aBmp.ReleaseAccess( pAcc );
|
|
||||||
|
|
||||||
if( pAcc1 )
|
|
||||||
aBmp1.ReleaseAccess( pAcc1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void* JPEGReader::CreateBitmap( void* pParam )
|
|
||||||
{
|
|
||||||
Size aSize( ((JPEGCreateBitmapParam*)pParam)->nWidth,
|
|
||||||
((JPEGCreateBitmapParam*)pParam)->nHeight );
|
|
||||||
sal_Bool bGray = ((JPEGCreateBitmapParam*)pParam)->bGray != 0;
|
|
||||||
|
|
||||||
void* pBmpBuf = NULL;
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
aBmp.ReleaseAccess( pAcc );
|
|
||||||
|
|
||||||
if( bGray )
|
|
||||||
{
|
|
||||||
BitmapPalette aGrayPal( 256 );
|
|
||||||
|
|
||||||
for( sal_uInt16 n = 0; n < 256; n++ )
|
|
||||||
{
|
|
||||||
const sal_uInt8 cGray = (sal_uInt8) n;
|
|
||||||
aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray );
|
|
||||||
}
|
|
||||||
|
|
||||||
aBmp = Bitmap( aSize, 8, &aGrayPal );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
aBmp = Bitmap( aSize, 24 );
|
|
||||||
|
|
||||||
if ( bSetLogSize )
|
|
||||||
{
|
|
||||||
unsigned long nUnit = ((JPEGCreateBitmapParam*)pParam)->density_unit;
|
|
||||||
|
|
||||||
if( ( ( 1 == nUnit ) || ( 2 == nUnit ) ) &&
|
|
||||||
( (JPEGCreateBitmapParam*) pParam )->X_density &&
|
|
||||||
( (JPEGCreateBitmapParam*) pParam )->Y_density )
|
|
||||||
{
|
|
||||||
Point aEmptyPoint;
|
|
||||||
Fraction aFractX( 1, ((JPEGCreateBitmapParam*)pParam)->X_density );
|
|
||||||
Fraction aFractY( 1, ((JPEGCreateBitmapParam*)pParam)->Y_density );
|
|
||||||
MapMode aMapMode( nUnit == 1 ? MAP_INCH : MAP_CM, aEmptyPoint, aFractX, aFractY );
|
|
||||||
Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MAP_100TH_MM );
|
|
||||||
|
|
||||||
aBmp.SetPrefSize( aPrefSize );
|
|
||||||
aBmp.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pAcc = aBmp.AcquireWriteAccess();
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
{
|
|
||||||
long nAlignedWidth;
|
|
||||||
|
|
||||||
const sal_uLong nFormat = pAcc->GetScanlineFormat();
|
|
||||||
|
|
||||||
if(
|
|
||||||
( bGray && ( BMP_FORMAT_8BIT_PAL == nFormat ) ) ||
|
|
||||||
( !bGray && ( BMP_FORMAT_24BIT_TC_RGB == nFormat ) )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
pBmpBuf = pAcc->GetBuffer();
|
|
||||||
nAlignedWidth = pAcc->GetScanlineSize();
|
|
||||||
((JPEGCreateBitmapParam*)pParam)->bTopDown = pAcc->IsTopDown();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nAlignedWidth = AlignedWidth4Bytes( aSize.Width() * ( bGray ? 8 : 24 ) );
|
|
||||||
((JPEGCreateBitmapParam*)pParam)->bTopDown = sal_True;
|
|
||||||
pBmpBuf = pBuffer = rtl_allocateMemory( nAlignedWidth * aSize.Height() );
|
|
||||||
}
|
|
||||||
((JPEGCreateBitmapParam*)pParam)->nAlignedWidth = nAlignedWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pBmpBuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void JPEGReader::FillBitmap()
|
|
||||||
{
|
|
||||||
if( pBuffer && pAcc )
|
|
||||||
{
|
|
||||||
HPBYTE pTmp;
|
|
||||||
BitmapColor aColor;
|
|
||||||
long nAlignedWidth;
|
|
||||||
long nWidth = pAcc->Width();
|
|
||||||
long nHeight = pAcc->Height();
|
|
||||||
|
|
||||||
if( pAcc->GetBitCount() == 8 )
|
|
||||||
{
|
|
||||||
BitmapColor* pCols = new BitmapColor[ 256 ];
|
|
||||||
|
|
||||||
for( sal_uInt16 n = 0; n < 256; n++ )
|
|
||||||
{
|
|
||||||
const sal_uInt8 cGray = (sal_uInt8) n;
|
|
||||||
pCols[ n ] = pAcc->GetBestMatchingColor( BitmapColor( cGray, cGray, cGray ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 8L );
|
|
||||||
|
|
||||||
for( long nY = 0L; nY < nHeight; nY++ )
|
|
||||||
{
|
|
||||||
pTmp = (sal_uInt8*) pBuffer + nY * nAlignedWidth;
|
|
||||||
|
|
||||||
for( long nX = 0L; nX < nWidth; nX++ )
|
|
||||||
pAcc->SetPixel( nY, nX, pCols[ *pTmp++ ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] pCols;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nAlignedWidth = AlignedWidth4Bytes( pAcc->Width() * 24L );
|
|
||||||
|
|
||||||
for( long nY = 0L; nY < nHeight; nY++ )
|
|
||||||
{
|
|
||||||
pTmp = (sal_uInt8*) pBuffer + nY * nAlignedWidth;
|
|
||||||
|
|
||||||
for( long nX = 0L; nX < nWidth; nX++ )
|
|
||||||
{
|
|
||||||
aColor.SetRed( *pTmp++ );
|
|
||||||
aColor.SetGreen( *pTmp++ );
|
|
||||||
aColor.SetBlue( *pTmp++ );
|
|
||||||
pAcc->SetPixel( nY, nX, aColor );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Graphic JPEGReader::CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines )
|
|
||||||
{
|
|
||||||
Graphic aGraphic;
|
|
||||||
const Size aSizePix( rBitmap.GetSizePixel() );
|
|
||||||
|
|
||||||
if( !nLastLines )
|
|
||||||
{
|
|
||||||
if( pAcc1 )
|
|
||||||
aBmp1.ReleaseAccess( pAcc1 );
|
|
||||||
|
|
||||||
aBmp1 = Bitmap( rBitmap.GetSizePixel(), 1 );
|
|
||||||
aBmp1.Erase( Color( COL_WHITE ) );
|
|
||||||
pAcc1 = aBmp1.AcquireWriteAccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( nLines && ( nLines < aSizePix.Height() ) )
|
|
||||||
{
|
|
||||||
if( pAcc1 )
|
|
||||||
{
|
|
||||||
const long nNewLines = nLines - nLastLines;
|
|
||||||
|
|
||||||
if( nNewLines )
|
|
||||||
{
|
|
||||||
pAcc1->SetFillColor( Color( COL_BLACK ) );
|
|
||||||
pAcc1->FillRect( Rectangle( Point( 0, nLastLines ),
|
|
||||||
Size( pAcc1->Width(), nNewLines ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
aBmp1.ReleaseAccess( pAcc1 );
|
|
||||||
aGraphic = BitmapEx( rBitmap, aBmp1 );
|
|
||||||
pAcc1 = aBmp1.AcquireWriteAccess();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
aGraphic = rBitmap;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
aGraphic = rBitmap;
|
|
||||||
|
|
||||||
nLastLines = nLines;
|
|
||||||
|
|
||||||
return aGraphic;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ReadState JPEGReader::Read( Graphic& rGraphic )
|
|
||||||
{
|
|
||||||
long nEndPos;
|
|
||||||
long nLines;
|
|
||||||
ReadState eReadState;
|
|
||||||
sal_Bool bRet = sal_False;
|
|
||||||
sal_uInt8 cDummy;
|
|
||||||
|
|
||||||
#if 1 // TODO: is it possible to get rid of this seek to the end?
|
|
||||||
// check if the stream's end is already available
|
|
||||||
rIStm.Seek( STREAM_SEEK_TO_END );
|
|
||||||
rIStm >> cDummy;
|
|
||||||
nEndPos = rIStm.Tell();
|
|
||||||
|
|
||||||
// else check if at least JPEGMINREAD bytes can be read
|
|
||||||
if( rIStm.GetError() == ERRCODE_IO_PENDING )
|
|
||||||
{
|
|
||||||
rIStm.ResetError();
|
|
||||||
if( ( nEndPos - nFormerPos ) < JPEGMINREAD )
|
|
||||||
{
|
|
||||||
rIStm.Seek( nLastPos );
|
|
||||||
return JPEGREAD_NEED_MORE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek back to the original position
|
|
||||||
rIStm.Seek( nLastPos );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Size aPreviewSize = GetPreviewSize();
|
|
||||||
SetJpegPreviewSizeHint( aPreviewSize.Width(), aPreviewSize.Height() );
|
|
||||||
|
|
||||||
// read the (partial) image
|
|
||||||
ReadJPEG( this, &rIStm, &nLines );
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
{
|
|
||||||
if( pBuffer )
|
|
||||||
{
|
|
||||||
FillBitmap();
|
|
||||||
rtl_freeMemory( pBuffer );
|
|
||||||
pBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
aBmp.ReleaseAccess( pAcc );
|
|
||||||
pAcc = NULL;
|
|
||||||
|
|
||||||
if( rIStm.GetError() == ERRCODE_IO_PENDING )
|
|
||||||
rGraphic = CreateIntermediateGraphic( aBmp, nLines );
|
|
||||||
else
|
|
||||||
rGraphic = aBmp;
|
|
||||||
|
|
||||||
bRet = sal_True;
|
|
||||||
}
|
|
||||||
else if( rIStm.GetError() == ERRCODE_IO_PENDING )
|
|
||||||
bRet = sal_True;
|
|
||||||
|
|
||||||
// Status setzen ( Pending hat immer Vorrang )
|
|
||||||
if( rIStm.GetError() == ERRCODE_IO_PENDING )
|
|
||||||
{
|
|
||||||
eReadState = JPEGREAD_NEED_MORE;
|
|
||||||
rIStm.ResetError();
|
|
||||||
nFormerPos = rIStm.Tell();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( bRet )
|
|
||||||
eReadState = JPEGREAD_OK;
|
|
||||||
else
|
|
||||||
eReadState = JPEGREAD_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return eReadState;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// - JPEGWriter -
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
JPEGWriter::JPEGWriter( SvStream& rStm, const uno::Sequence< beans::PropertyValue >* pFilterData, bool* pExportWasGrey ) :
|
|
||||||
rOStm ( rStm ),
|
|
||||||
pAcc ( NULL ),
|
|
||||||
pBuffer ( NULL ),
|
|
||||||
pExpWasGrey ( pExportWasGrey )
|
|
||||||
{
|
|
||||||
FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
|
|
||||||
bGreys = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) ), 0 ) != 0;
|
|
||||||
nQuality = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ), 75 );
|
|
||||||
|
|
||||||
if ( pFilterData )
|
|
||||||
{
|
|
||||||
int nArgs = pFilterData->getLength();
|
|
||||||
const beans::PropertyValue* pValues = pFilterData->getConstArray();
|
|
||||||
while( nArgs-- )
|
|
||||||
{
|
|
||||||
if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ) ) )
|
|
||||||
{
|
|
||||||
pValues->Value >>= xStatusIndicator;
|
|
||||||
}
|
|
||||||
pValues++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void* JPEGWriter::GetScanline( long nY )
|
|
||||||
{
|
|
||||||
void* pScanline = NULL;
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
{
|
|
||||||
if( bNative )
|
|
||||||
pScanline = pAcc->GetScanline( nY );
|
|
||||||
else if( pBuffer )
|
|
||||||
{
|
|
||||||
BitmapColor aColor;
|
|
||||||
long nWidth = pAcc->Width();
|
|
||||||
sal_uInt8* pTmp = pBuffer;
|
|
||||||
|
|
||||||
if( pAcc->HasPalette() )
|
|
||||||
{
|
|
||||||
for( long nX = 0L; nX < nWidth; nX++ )
|
|
||||||
{
|
|
||||||
aColor = pAcc->GetPaletteColor( (sal_uInt8) pAcc->GetPixel( nY, nX ) );
|
|
||||||
*pTmp++ = aColor.GetRed();
|
|
||||||
if ( bGreys )
|
|
||||||
continue;
|
|
||||||
*pTmp++ = aColor.GetGreen();
|
|
||||||
*pTmp++ = aColor.GetBlue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( long nX = 0L; nX < nWidth; nX++ )
|
|
||||||
{
|
|
||||||
aColor = pAcc->GetPixel( nY, nX );
|
|
||||||
*pTmp++ = aColor.GetRed();
|
|
||||||
if ( bGreys )
|
|
||||||
continue;
|
|
||||||
*pTmp++ = aColor.GetGreen();
|
|
||||||
*pTmp++ = aColor.GetBlue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pScanline = pBuffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pScanline;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
sal_Bool JPEGWriter::Write( const Graphic& rGraphic )
|
|
||||||
{
|
|
||||||
sal_Bool bRet = sal_False;
|
|
||||||
|
|
||||||
if ( xStatusIndicator.is() )
|
|
||||||
{
|
|
||||||
rtl::OUString aMsg;
|
|
||||||
xStatusIndicator->start( aMsg, 100 );
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap aGraphicBmp( rGraphic.GetBitmap() );
|
|
||||||
|
|
||||||
if ( bGreys )
|
|
||||||
{
|
|
||||||
if ( !aGraphicBmp.Convert( BMP_CONVERSION_8BIT_GREYS ) )
|
|
||||||
aGraphicBmp = rGraphic.GetBitmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
pAcc = aGraphicBmp.AcquireReadAccess();
|
|
||||||
|
|
||||||
if ( !bGreys ) // bitmap was not explicitely converted into greyscale,
|
|
||||||
{ // check if source is greyscale only
|
|
||||||
|
|
||||||
sal_Bool bIsGrey = sal_True;
|
|
||||||
|
|
||||||
long nWidth = pAcc->Width();
|
|
||||||
for ( long nY = 0; bIsGrey && ( nY < pAcc->Height() ); nY++ )
|
|
||||||
{
|
|
||||||
BitmapColor aColor;
|
|
||||||
for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ )
|
|
||||||
{
|
|
||||||
aColor = pAcc->HasPalette() ? pAcc->GetPaletteColor( (sal_uInt8) pAcc->GetPixel( nY, nX ) )
|
|
||||||
: pAcc->GetPixel( nY, nX );
|
|
||||||
bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( bIsGrey )
|
|
||||||
bGreys = sal_True;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pExpWasGrey )
|
|
||||||
*pExpWasGrey = bGreys;
|
|
||||||
|
|
||||||
if( pAcc )
|
|
||||||
{
|
|
||||||
bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
|
|
||||||
|
|
||||||
if( !bNative )
|
|
||||||
pBuffer = new sal_uInt8[ AlignedWidth4Bytes( bGreys ? pAcc->Width() * 8L : pAcc->Width() * 24L ) ];
|
|
||||||
|
|
||||||
JPEGCallbackStruct aCallbackData;
|
|
||||||
aCallbackData.xStatusIndicator = xStatusIndicator;
|
|
||||||
bRet = (sal_Bool) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), bGreys, nQuality, &aCallbackData );
|
|
||||||
|
|
||||||
delete[] pBuffer;
|
|
||||||
pBuffer = NULL;
|
|
||||||
|
|
||||||
aGraphicBmp.ReleaseAccess( pAcc );
|
|
||||||
pAcc = NULL;
|
|
||||||
}
|
|
||||||
if ( xStatusIndicator.is() )
|
|
||||||
xStatusIndicator->end();
|
|
||||||
|
|
||||||
return bRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// - ImportJPEG -
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
sal_Bool ImportJPEG( SvStream& rStm, Graphic& rGraphic, void* pCallerData, sal_Int32 nImportFlags )
|
|
||||||
{
|
|
||||||
JPEGReader* pJPEGReader = (JPEGReader*) rGraphic.GetContext();
|
|
||||||
ReadState eReadState;
|
|
||||||
sal_Bool bRet = sal_True;
|
|
||||||
|
|
||||||
if( !pJPEGReader )
|
|
||||||
pJPEGReader = new JPEGReader( rStm, pCallerData, ( nImportFlags & GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG ) != 0 );
|
|
||||||
|
|
||||||
if( nImportFlags & GRFILTER_I_FLAGS_FOR_PREVIEW )
|
|
||||||
pJPEGReader->SetPreviewSize( Size(128,128) );
|
|
||||||
else
|
|
||||||
pJPEGReader->DisablePreviewMode();
|
|
||||||
|
|
||||||
rGraphic.SetContext( NULL );
|
|
||||||
eReadState = pJPEGReader->Read( rGraphic );
|
|
||||||
|
|
||||||
if( eReadState == JPEGREAD_ERROR )
|
|
||||||
{
|
|
||||||
bRet = sal_False;
|
|
||||||
delete pJPEGReader;
|
|
||||||
}
|
|
||||||
else if( eReadState == JPEGREAD_OK )
|
|
||||||
delete pJPEGReader;
|
|
||||||
else
|
|
||||||
rGraphic.SetContext( pJPEGReader );
|
|
||||||
|
|
||||||
return bRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------
|
|
||||||
// - ExportJPEG -
|
|
||||||
// --------------
|
|
||||||
|
|
||||||
sal_Bool ExportJPEG( SvStream& rOStm, const Graphic& rGraphic,
|
|
||||||
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData,
|
|
||||||
bool* pExportWasGrey
|
|
||||||
)
|
|
||||||
{
|
|
||||||
JPEGWriter aJPEGWriter( rOStm, pFilterData, pExportWasGrey );
|
|
||||||
return aJPEGWriter.Write( rGraphic );
|
|
||||||
}
|
|
|
@ -1,284 +0,0 @@
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
||||||
*
|
|
||||||
* OpenOffice.org - a multi-platform office productivity suite
|
|
||||||
*
|
|
||||||
* This file is part of OpenOffice.org.
|
|
||||||
*
|
|
||||||
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License version 3
|
|
||||||
* only, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License version 3 for more details
|
|
||||||
* (a copy is included in the LICENSE file that accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* version 3 along with OpenOffice.org. If not, see
|
|
||||||
* <http://www.openoffice.org/license.html>
|
|
||||||
* for a copy of the LGPLv3 License.
|
|
||||||
*
|
|
||||||
************************************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "setjmp.h"
|
|
||||||
#include "jpeg/jpeglib.h"
|
|
||||||
#include "jpeg/jerror.h"
|
|
||||||
#include "jpeg.h"
|
|
||||||
#include "rtl/alloc.h"
|
|
||||||
#include "osl/diagnose.h"
|
|
||||||
|
|
||||||
struct my_error_mgr
|
|
||||||
{
|
|
||||||
struct jpeg_error_mgr pub;
|
|
||||||
jmp_buf setjmp_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
void jpeg_svstream_src (j_decompress_ptr cinfo, void* infile);
|
|
||||||
void jpeg_svstream_dest (j_compress_ptr cinfo, void* outfile);
|
|
||||||
|
|
||||||
METHODDEF( void )
|
|
||||||
my_error_exit (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
|
||||||
(*cinfo->err->output_message) (cinfo);
|
|
||||||
longjmp(myerr->setjmp_buffer, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHODDEF( void )
|
|
||||||
my_output_message (j_common_ptr cinfo)
|
|
||||||
{
|
|
||||||
char buffer[JMSG_LENGTH_MAX];
|
|
||||||
(*cinfo->err->format_message) (cinfo, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: when incompatible changes are possible again
|
|
||||||
the preview size hint should be redone */
|
|
||||||
static int nPreviewWidth = 0;
|
|
||||||
static int nPreviewHeight = 0;
|
|
||||||
void SetJpegPreviewSizeHint( int nWidth, int nHeight )
|
|
||||||
{
|
|
||||||
nPreviewWidth = nWidth;
|
|
||||||
nPreviewHeight = nHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadJPEG( void* pJPEGReader, void* pIStm, long* pLines )
|
|
||||||
{
|
|
||||||
struct jpeg_decompress_struct cinfo;
|
|
||||||
struct my_error_mgr jerr;
|
|
||||||
struct JPEGCreateBitmapParam aCreateBitmapParam;
|
|
||||||
HPBYTE pDIB;
|
|
||||||
HPBYTE pTmp;
|
|
||||||
long nWidth;
|
|
||||||
long nHeight;
|
|
||||||
long nAlignedWidth;
|
|
||||||
JSAMPLE * range_limit;
|
|
||||||
HPBYTE pScanLineBuffer = NULL;
|
|
||||||
long nScanLineBufferComponents = 0;
|
|
||||||
// declare bDecompCreated volatile because of gcc
|
|
||||||
// warning: variable 'bDecompCreated' might be clobbered by `longjmp' or `vfork'
|
|
||||||
volatile long bDecompCreated = 0;
|
|
||||||
|
|
||||||
/* Falls der Stream nicht ausreicht (IO_PENDING)
|
|
||||||
wird ueber ein longjmp in der Schleife nach Exit
|
|
||||||
gesprungen, wir geben dann die Anzahl
|
|
||||||
der bisher bearbeiteten Scanlines zurueck*/
|
|
||||||
if ( setjmp( jerr.setjmp_buffer ) )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error( &jerr.pub );
|
|
||||||
jerr.pub.error_exit = my_error_exit;
|
|
||||||
jerr.pub.output_message = my_output_message;
|
|
||||||
|
|
||||||
jpeg_create_decompress( &cinfo );
|
|
||||||
bDecompCreated = 1;
|
|
||||||
jpeg_svstream_src( &cinfo, pIStm );
|
|
||||||
jpeg_read_header( &cinfo, sal_True );
|
|
||||||
|
|
||||||
cinfo.scale_num = 1;
|
|
||||||
cinfo.scale_denom = 1;
|
|
||||||
cinfo.output_gamma = 1.0;
|
|
||||||
cinfo.raw_data_out = sal_False;
|
|
||||||
cinfo.quantize_colors = sal_False;
|
|
||||||
if ( cinfo.jpeg_color_space == JCS_YCbCr )
|
|
||||||
cinfo.out_color_space = JCS_RGB;
|
|
||||||
else if ( cinfo.jpeg_color_space == JCS_YCCK )
|
|
||||||
cinfo.out_color_space = JCS_CMYK;
|
|
||||||
|
|
||||||
OSL_ASSERT(cinfo.out_color_space == JCS_CMYK || cinfo.out_color_space == JCS_GRAYSCALE || cinfo.out_color_space == JCS_RGB);
|
|
||||||
|
|
||||||
/* change scale for preview import */
|
|
||||||
if( nPreviewWidth || nPreviewHeight )
|
|
||||||
{
|
|
||||||
if( nPreviewWidth == 0 ) {
|
|
||||||
nPreviewWidth = ( cinfo.image_width*nPreviewHeight )/cinfo.image_height;
|
|
||||||
if( nPreviewWidth <= 0 )
|
|
||||||
nPreviewWidth = 1;
|
|
||||||
} else if( nPreviewHeight == 0 ) {
|
|
||||||
nPreviewHeight = ( cinfo.image_height*nPreviewWidth )/cinfo.image_width;
|
|
||||||
if( nPreviewHeight <= 0 )
|
|
||||||
nPreviewHeight = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( cinfo.scale_denom = 1; cinfo.scale_denom < 8; cinfo.scale_denom *= 2 )
|
|
||||||
{
|
|
||||||
if( cinfo.image_width < nPreviewWidth * cinfo.scale_denom )
|
|
||||||
break;
|
|
||||||
if( cinfo.image_height < nPreviewHeight * cinfo.scale_denom )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( cinfo.scale_denom > 1 )
|
|
||||||
{
|
|
||||||
cinfo.dct_method = JDCT_FASTEST;
|
|
||||||
cinfo.do_fancy_upsampling = sal_False;
|
|
||||||
cinfo.do_block_smoothing = sal_False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_start_decompress( &cinfo );
|
|
||||||
|
|
||||||
nWidth = cinfo.output_width;
|
|
||||||
nHeight = cinfo.output_height;
|
|
||||||
aCreateBitmapParam.nWidth = nWidth;
|
|
||||||
aCreateBitmapParam.nHeight = nHeight;
|
|
||||||
|
|
||||||
aCreateBitmapParam.density_unit = cinfo.density_unit;
|
|
||||||
aCreateBitmapParam.X_density = cinfo.X_density;
|
|
||||||
aCreateBitmapParam.Y_density = cinfo.Y_density;
|
|
||||||
aCreateBitmapParam.bGray = cinfo.output_components == 1;
|
|
||||||
pDIB = CreateBitmap( pJPEGReader, &aCreateBitmapParam );
|
|
||||||
nAlignedWidth = aCreateBitmapParam.nAlignedWidth;
|
|
||||||
range_limit=cinfo.sample_range_limit;
|
|
||||||
|
|
||||||
if ( cinfo.out_color_space == JCS_CMYK )
|
|
||||||
{
|
|
||||||
nScanLineBufferComponents = cinfo.output_width * 4;
|
|
||||||
pScanLineBuffer = rtl_allocateMemory( nScanLineBufferComponents );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pDIB )
|
|
||||||
{
|
|
||||||
if( aCreateBitmapParam.bTopDown )
|
|
||||||
pTmp = pDIB;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pTmp = pDIB + ( nHeight - 1 ) * nAlignedWidth;
|
|
||||||
nAlignedWidth = -nAlignedWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( *pLines = 0; *pLines < nHeight; (*pLines)++ )
|
|
||||||
{
|
|
||||||
if (pScanLineBuffer!=NULL) { // in other words cinfo.out_color_space == JCS_CMYK
|
|
||||||
int i;
|
|
||||||
int j;
|
|
||||||
jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pScanLineBuffer, 1 );
|
|
||||||
// convert CMYK to RGB
|
|
||||||
for( i=0, j=0; i < nScanLineBufferComponents; i+=4, j+=3 )
|
|
||||||
{
|
|
||||||
int c_=255-pScanLineBuffer[i+0];
|
|
||||||
int m_=255-pScanLineBuffer[i+1];
|
|
||||||
int y_=255-pScanLineBuffer[i+2];
|
|
||||||
int k_=255-pScanLineBuffer[i+3];
|
|
||||||
pTmp[j+0]=range_limit[ 255L - ( c_ + k_ ) ];
|
|
||||||
pTmp[j+1]=range_limit[ 255L - ( m_ + k_ ) ];
|
|
||||||
pTmp[j+2]=range_limit[ 255L - ( y_ + k_ ) ];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
jpeg_read_scanlines( &cinfo, (JSAMPARRAY) &pTmp, 1 );
|
|
||||||
}
|
|
||||||
/* PENDING ??? */
|
|
||||||
if ( cinfo.err->msg_code == 113 )
|
|
||||||
break;
|
|
||||||
|
|
||||||
pTmp += nAlignedWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_finish_decompress( &cinfo );
|
|
||||||
if (pScanLineBuffer!=NULL) {
|
|
||||||
rtl_freeMemory( pScanLineBuffer );
|
|
||||||
pScanLineBuffer=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
|
|
||||||
if( bDecompCreated )
|
|
||||||
jpeg_destroy_decompress( &cinfo );
|
|
||||||
}
|
|
||||||
|
|
||||||
long WriteJPEG( void* pJPEGWriter, void* pOStm,
|
|
||||||
long nWidth, long nHeight, long bGreys,
|
|
||||||
long nQualityPercent, void* pCallbackData )
|
|
||||||
{
|
|
||||||
struct jpeg_compress_struct cinfo;
|
|
||||||
struct my_error_mgr jerr;
|
|
||||||
void* pScanline;
|
|
||||||
long nY;
|
|
||||||
// declare bCompCreated, bRet volatile because of gcc
|
|
||||||
// warning: variable 'bCompCreated' might be clobbered by `longjmp' or `vfork'
|
|
||||||
volatile long bCompCreated = 0;
|
|
||||||
volatile long bRet = 0;
|
|
||||||
|
|
||||||
if ( setjmp( jerr.setjmp_buffer ) )
|
|
||||||
goto Exit;
|
|
||||||
|
|
||||||
cinfo.err = jpeg_std_error( &jerr.pub );
|
|
||||||
jerr.pub.error_exit = my_error_exit;
|
|
||||||
jerr.pub.output_message = my_output_message;
|
|
||||||
|
|
||||||
jpeg_create_compress( &cinfo );
|
|
||||||
bCompCreated = 1;
|
|
||||||
|
|
||||||
jpeg_svstream_dest( &cinfo, pOStm );
|
|
||||||
|
|
||||||
cinfo.image_width = (JDIMENSION) nWidth;
|
|
||||||
cinfo.image_height = (JDIMENSION) nHeight;
|
|
||||||
if ( bGreys )
|
|
||||||
{
|
|
||||||
cinfo.input_components = 1;
|
|
||||||
cinfo.in_color_space = JCS_GRAYSCALE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cinfo.input_components = 3;
|
|
||||||
cinfo.in_color_space = JCS_RGB;
|
|
||||||
}
|
|
||||||
|
|
||||||
jpeg_set_defaults( &cinfo );
|
|
||||||
jpeg_set_quality( &cinfo, (int) nQualityPercent, sal_False );
|
|
||||||
|
|
||||||
if ( ( nWidth > 128 ) || ( nHeight > 128 ) )
|
|
||||||
jpeg_simple_progression( &cinfo );
|
|
||||||
|
|
||||||
jpeg_start_compress( &cinfo, sal_True );
|
|
||||||
|
|
||||||
for( nY = 0; nY < nHeight; nY++ )
|
|
||||||
{
|
|
||||||
pScanline = GetScanline( pJPEGWriter, nY );
|
|
||||||
|
|
||||||
if( pScanline )
|
|
||||||
jpeg_write_scanlines( &cinfo, (JSAMPARRAY) &pScanline, 1 );
|
|
||||||
|
|
||||||
if( JPEGCallback( pCallbackData, nY * 100L / nHeight ) )
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bRet = 1;
|
|
||||||
|
|
||||||
jpeg_finish_compress(&cinfo);
|
|
||||||
|
|
||||||
Exit:
|
|
||||||
|
|
||||||
if ( bCompCreated )
|
|
||||||
jpeg_destroy_compress( &cinfo );
|
|
||||||
|
|
||||||
return bRet;
|
|
||||||
}
|
|
Loading…
Reference in a new issue