/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_filter.hxx" #include #include "giflzwc.hxx" // ---------------------------- // - GIFImageDataOutputStream - // ---------------------------- class GIFImageDataOutputStream { private: void FlushBlockBuf(); inline void FlushBitsBufsFullBytes(); SvStream& rStream; sal_uInt8* pBlockBuf; sal_uInt8 nBlockBufSize; sal_uLong nBitsBuf; sal_uInt16 nBitsBufSize; public: GIFImageDataOutputStream( SvStream & rGIF, sal_uInt8 nLZWDataSize ); ~GIFImageDataOutputStream(); inline void WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen ); }; // ------------------------------------------------------------------------ inline void GIFImageDataOutputStream::FlushBitsBufsFullBytes() { while (nBitsBufSize>=8) { if( nBlockBufSize==255 ) FlushBlockBuf(); pBlockBuf[nBlockBufSize++] = (sal_uInt8) nBitsBuf; nBitsBuf >>= 8; nBitsBufSize -= 8; } } // ------------------------------------------------------------------------ inline void GIFImageDataOutputStream::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen ) { if( nBitsBufSize+nCodeLen>32 ) FlushBitsBufsFullBytes(); nBitsBuf |= (sal_uLong) nCode << nBitsBufSize; nBitsBufSize = nBitsBufSize + nCodeLen; } // ------------------------------------------------------------------------ GIFImageDataOutputStream::GIFImageDataOutputStream( SvStream & rGIF, sal_uInt8 nLZWDataSize ) : rStream(rGIF) { pBlockBuf = new sal_uInt8[ 255 ]; nBlockBufSize = 0; nBitsBufSize = 0; nBitsBuf = 0; rStream << nLZWDataSize; } // ------------------------------------------------------------------------ GIFImageDataOutputStream::~GIFImageDataOutputStream() { WriteBits(0,7); FlushBitsBufsFullBytes(); FlushBlockBuf(); rStream << (sal_uInt8)0; delete[] pBlockBuf; } // ------------------------------------------------------------------------ void GIFImageDataOutputStream::FlushBlockBuf() { if( nBlockBufSize ) { rStream << (sal_uInt8) nBlockBufSize; rStream.Write( pBlockBuf,nBlockBufSize ); nBlockBufSize = 0; } } // ------------------- // - GIFLZWCTreeNode - // ------------------- struct GIFLZWCTreeNode { GIFLZWCTreeNode* pBrother; // naechster Knoten, der den selben Vater hat GIFLZWCTreeNode* pFirstChild; // erster Sohn sal_uInt16 nCode; // Der Code fuer den String von Pixelwerten, der sich ergibt, wenn sal_uInt16 nValue; // Der Pixelwert }; // -------------------- // - GIFLZWCompressor - // -------------------- GIFLZWCompressor::GIFLZWCompressor() { pIDOS=NULL; } // ------------------------------------------------------------------------ GIFLZWCompressor::~GIFLZWCompressor() { if (pIDOS!=NULL) EndCompression(); } // ------------------------------------------------------------------------ void GIFLZWCompressor::StartCompression( SvStream& rGIF, sal_uInt16 nPixelSize ) { if( !pIDOS ) { sal_uInt16 i; nDataSize = nPixelSize; if( nDataSize < 2 ) nDataSize=2; nClearCode=1<WriteBits( nClearCode,nCodeSize ); } } // ------------------------------------------------------------------------ void GIFLZWCompressor::Compress( HPBYTE pSrc, sal_uLong nSize ) { if( pIDOS ) { GIFLZWCTreeNode* p; sal_uInt16 i; sal_uInt8 nV; if( !pPrefix && nSize ) { pPrefix=pTable+(*pSrc++); nSize--; } while( nSize ) { nSize--; nV=*pSrc++; for( p=pPrefix->pFirstChild; p!=NULL; p=p->pBrother ) { if (p->nValue==nV) break; } if( p) pPrefix=p; else { pIDOS->WriteBits(pPrefix->nCode,nCodeSize); if (nTableSize==4096) { pIDOS->WriteBits(nClearCode,nCodeSize); for (i=0; ipBrother=pPrefix->pFirstChild; pPrefix->pFirstChild=p; p->nValue=nV; p->pFirstChild=NULL; } pPrefix=pTable+nV; } } } } // ------------------------------------------------------------------------ void GIFLZWCompressor::EndCompression() { if( pIDOS ) { if( pPrefix ) pIDOS->WriteBits(pPrefix->nCode,nCodeSize); pIDOS->WriteBits( nEOICode,nCodeSize ); delete[] pTable; delete pIDOS; pIDOS=NULL; } }