1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/stream.hxx>
22 #include "giflzwc.hxx"
24 // ----------------------------
25 // - GIFImageDataOutputStream -
26 // ----------------------------
28 class GIFImageDataOutputStream
33 inline void FlushBitsBufsFullBytes();
37 sal_uInt8 nBlockBufSize
;
39 sal_uInt16 nBitsBufSize
;
43 GIFImageDataOutputStream( SvStream
& rGIF
, sal_uInt8 nLZWDataSize
);
44 ~GIFImageDataOutputStream();
46 inline void WriteBits( sal_uInt16 nCode
, sal_uInt16 nCodeLen
);
49 // ------------------------------------------------------------------------
51 inline void GIFImageDataOutputStream::FlushBitsBufsFullBytes()
53 while (nBitsBufSize
>=8)
55 if( nBlockBufSize
==255 )
58 pBlockBuf
[nBlockBufSize
++] = (sal_uInt8
) nBitsBuf
;
64 // ------------------------------------------------------------------------
66 inline void GIFImageDataOutputStream::WriteBits( sal_uInt16 nCode
, sal_uInt16 nCodeLen
)
68 if( nBitsBufSize
+nCodeLen
>32 )
69 FlushBitsBufsFullBytes();
71 nBitsBuf
|= (sal_uLong
) nCode
<< nBitsBufSize
;
72 nBitsBufSize
= nBitsBufSize
+ nCodeLen
;
75 // ------------------------------------------------------------------------
77 GIFImageDataOutputStream::GIFImageDataOutputStream( SvStream
& rGIF
, sal_uInt8 nLZWDataSize
) :
80 pBlockBuf
= new sal_uInt8
[ 255 ];
84 rStream
<< nLZWDataSize
;
87 // ------------------------------------------------------------------------
90 GIFImageDataOutputStream::~GIFImageDataOutputStream()
93 FlushBitsBufsFullBytes();
95 rStream
<< (sal_uInt8
)0;
99 // ------------------------------------------------------------------------
101 void GIFImageDataOutputStream::FlushBlockBuf()
105 rStream
<< (sal_uInt8
) nBlockBufSize
;
106 rStream
.Write( pBlockBuf
,nBlockBufSize
);
111 // -------------------
112 // - GIFLZWCTreeNode -
113 // -------------------
115 struct GIFLZWCTreeNode
118 GIFLZWCTreeNode
* pBrother
; // next node which has the same father
119 GIFLZWCTreeNode
* pFirstChild
; // first
120 sal_uInt16 nCode
; // the code for the string of pixel values which comes about
121 sal_uInt16 nValue
; // the pixel value
124 // --------------------
125 // - GIFLZWCompressor -
126 // --------------------
128 GIFLZWCompressor::GIFLZWCompressor()
133 // ------------------------------------------------------------------------
135 GIFLZWCompressor::~GIFLZWCompressor()
137 if (pIDOS
!=NULL
) EndCompression();
140 // ------------------------------------------------------------------------
142 void GIFLZWCompressor::StartCompression( SvStream
& rGIF
, sal_uInt16 nPixelSize
)
148 nDataSize
= nPixelSize
;
153 nClearCode
=1<<nDataSize
;
154 nEOICode
=nClearCode
+1;
155 nTableSize
=nEOICode
+1;
156 nCodeSize
=nDataSize
+1;
158 pIDOS
=new GIFImageDataOutputStream(rGIF
,(sal_uInt8
)nDataSize
);
159 pTable
=new GIFLZWCTreeNode
[4096];
161 for (i
=0; i
<4096; i
++)
163 pTable
[i
].pBrother
= pTable
[i
].pFirstChild
= NULL
;
164 pTable
[i
].nValue
= (sal_uInt8
) ( pTable
[i
].nCode
= i
);
168 pIDOS
->WriteBits( nClearCode
,nCodeSize
);
172 // ------------------------------------------------------------------------
174 void GIFLZWCompressor::Compress( HPBYTE pSrc
, sal_uLong nSize
)
182 if( !pPrefix
&& nSize
)
184 pPrefix
=pTable
+(*pSrc
++);
192 for( p
=pPrefix
->pFirstChild
; p
!=NULL
; p
=p
->pBrother
)
202 pIDOS
->WriteBits(pPrefix
->nCode
,nCodeSize
);
204 if (nTableSize
==4096)
206 pIDOS
->WriteBits(nClearCode
,nCodeSize
);
208 for (i
=0; i
<nClearCode
; i
++)
209 pTable
[i
].pFirstChild
=NULL
;
211 nCodeSize
=nDataSize
+1;
212 nTableSize
=nEOICode
+1;
216 if(nTableSize
==(sal_uInt16
)(1<<nCodeSize
))
219 p
=pTable
+(nTableSize
++);
220 p
->pBrother
=pPrefix
->pFirstChild
;
221 pPrefix
->pFirstChild
=p
;
232 // ------------------------------------------------------------------------
234 void GIFLZWCompressor::EndCompression()
239 pIDOS
->WriteBits(pPrefix
->nCode
,nCodeSize
);
241 pIDOS
->WriteBits( nEOICode
,nCodeSize
);
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */