Updating the changelog in the VERSION file, and version_sync.
[shapes.git] / source / pdfstructure.cc
blob1ac411fd043c7790867c47d5309c70602ae8486e
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include <iomanip>
20 #include <cstdlib>
21 #include <cstring>
22 #include <cstdio>
23 #include <zlib.h>
25 #include "pdfstructure.h"
26 #include "simplepdfo.h"
27 #include "simplepdfi.h"
28 #include "autoonoff.h"
30 using namespace std;
32 using namespace SimplePDF;
34 /****************/
36 SimplePDF::PDF_Object::PDF_Object( )
37 : complete( false )
38 { }
39 SimplePDF::PDF_Object::~PDF_Object( )
40 { }
41 void
42 SimplePDF::PDF_Object::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
44 throw "This function, PDF_Object::writeTo, must not be called. It is practically purely virtual.";
46 RefCountPtr< PDF_Object >
47 SimplePDF::PDF_Object::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
49 return self;
52 /****************/
54 template< class S >
55 RefCountPtr< S >
56 SimplePDF::down_cast_follow( RefCountPtr< PDF_Object > maybeIndirect )
59 const PDF_Indirect_in * theIndirect( dynamic_cast< const PDF_Indirect_in * >( maybeIndirect.getPtr( ) ) );
60 if( theIndirect != 0 )
62 return theIndirect->PDFin->follow< S >( maybeIndirect );
66 const PDF_Indirect_out * theIndirect( dynamic_cast< const PDF_Indirect_out * >( maybeIndirect.getPtr( ) ) );
67 if( theIndirect != 0 )
69 return SimplePDF::down_cast_follow< S >( theIndirect->obj );
73 return maybeIndirect.down_cast< S >( );
76 namespace SimplePDF
78 template< >
79 RefCountPtr< SimplePDF::PDF_Float >
80 down_cast_follow< SimplePDF::PDF_Float >( RefCountPtr< PDF_Object > maybeIndirect )
83 const PDF_Indirect_in * theIndirect( dynamic_cast< const PDF_Indirect_in * >( maybeIndirect.getPtr( ) ) );
84 if( theIndirect != 0 )
86 return theIndirect->PDFin->follow< SimplePDF::PDF_Float >( maybeIndirect );
90 const PDF_Indirect_out * theIndirect( dynamic_cast< const PDF_Indirect_out * >( maybeIndirect.getPtr( ) ) );
91 if( theIndirect != 0 )
93 return SimplePDF::down_cast_follow< SimplePDF::PDF_Float >( theIndirect->obj );
97 RefCountPtr< PDF_Int > res( maybeIndirect.down_cast< PDF_Int >( ) );
98 if( res != NullPtr< PDF_Int >( ) )
100 return RefCountPtr< PDF_Float >( new PDF_Float( res->value( ) ) );
103 return maybeIndirect.down_cast< SimplePDF::PDF_Float >( );
107 namespace SimplePDF
109 template RefCountPtr< SimplePDF::PDF_Vector > down_cast_follow< SimplePDF::PDF_Vector >( RefCountPtr< PDF_Object > );
112 /****************/
114 SimplePDF::PDF_Null::PDF_Null( )
116 SimplePDF::PDF_Null::~PDF_Null( )
119 void
120 SimplePDF::PDF_Null::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
122 os << "null" ;
125 /****************/
127 SimplePDF::PDF_Boolean::PDF_Boolean( ValueType _value )
128 : my_value( _value )
130 SimplePDF::PDF_Boolean::~PDF_Boolean( )
133 SimplePDF::PDF_Boolean::ValueType
134 SimplePDF::PDF_Boolean::value( ) const
136 return my_value;
139 void
140 SimplePDF::PDF_Boolean::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
142 if( my_value )
144 os << "true" ;
146 else
148 os << "false" ;
152 /****************/
154 SimplePDF::PDF_Int::PDF_Int( PDF_Int::ValueType _value )
155 : my_value( _value )
157 SimplePDF::PDF_Int::PDF_Int( const char * strvalue )
159 /* How can it be that end shall be non-const, while strvalue is const? */
160 // const char * end;
161 char * end;
162 my_value = strtol( strvalue, & end, 10 );
163 if( *end != '\0' )
165 throw "Internal error: Bad numeric int format";
168 SimplePDF::PDF_Int::~PDF_Int( )
171 PDF_Int::ValueType
172 SimplePDF::PDF_Int::value( ) const
174 return my_value;
177 void
178 SimplePDF::PDF_Int::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
180 os << my_value ;
183 /****************/
185 SimplePDF::PDF_Float::PDF_Float( PDF_Float::ValueType _value )
186 : my_value( _value )
188 SimplePDF::PDF_Float::PDF_Float( const char * strvalue )
190 /* How can it be that end shall be non-const, while strvalue is const? */
191 // const char * end;
192 char * end;
193 my_value = strtod( strvalue, & end );
194 if( *end != '\0' )
196 throw( "Internal error: Bad numeric float format" );
199 SimplePDF::PDF_Float::~PDF_Float( )
202 SimplePDF::PDF_Float::ValueType PDF_Float::value( ) const
204 return my_value;
207 void
208 SimplePDF::PDF_Float::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
210 os << my_value ;
213 /****************/
215 SimplePDF::PDF_String::PDF_String( )
217 SimplePDF::PDF_String::~PDF_String( )
220 /****************/
222 SimplePDF::PDF_LiteralString::PDF_LiteralString( const string & _str )
223 : my_str( _str )
225 SimplePDF::PDF_LiteralString::PDF_LiteralString( const char * _str )
226 : my_str( _str )
228 SimplePDF::PDF_LiteralString::PDF_LiteralString( const list< RefCountPtr< char > > & strs )
230 size_t length( 0 );
231 typedef list< RefCountPtr< char > >::const_iterator I;
232 for( I i( strs.begin( ) ); i != strs.end( ); ++i )
234 length += strlen( i->getPtr( ) );
236 RefCountPtr< char > mem( new char[ length + 1 ] );
237 char * dst = mem.getPtr( );
238 for( I i( strs.begin( ) ); i != strs.end( ); ++i )
240 strcpy( dst, i->getPtr( ) );
241 dst += strlen( i->getPtr( ) );
243 *dst = '\0';
244 my_str = mem.getPtr( );
246 SimplePDF::PDF_LiteralString::~PDF_LiteralString( )
249 const string &
250 SimplePDF::PDF_LiteralString::str( ) const
252 return my_str;
255 void
256 SimplePDF::PDF_LiteralString::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
258 os << "(" ;
259 for( const char * src = my_str.c_str( ); *src != '\0'; ++src )
261 switch( *src )
263 case '(':
264 os << "\\(" ;
265 break;
266 case ')':
267 os << "\\)" ;
268 break;
269 case '\\':
270 os << "\\\\" ;
271 break;
272 default:
273 os << *src ;
276 os << ")" ;
279 /****************/
281 SimplePDF::PDF_HexString::PDF_HexString( const string & _hexstr )
282 : my_hexstr( _hexstr )
284 SimplePDF::PDF_HexString::PDF_HexString( const char * _hexstr )
285 : my_hexstr( _hexstr )
287 SimplePDF::PDF_HexString::~PDF_HexString( )
290 const string &
291 SimplePDF::PDF_HexString::hexstr( ) const
293 return my_hexstr;
296 void
297 SimplePDF::PDF_HexString::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
299 os << "<" << my_hexstr << ">" ;
302 /****************/
304 SimplePDF::PDF_Name::PDF_Name( const string & _name )
305 : my_name( _name )
307 SimplePDF::PDF_Name::~PDF_Name( )
310 const string &
311 SimplePDF::PDF_Name::name( ) const
313 return my_name;
316 void
317 SimplePDF::PDF_Name::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
319 os << "/" << my_name ;
322 ostream & SimplePDF::operator << ( std::ostream & os, const PDF_Name & self )
324 return os << "/" << self.my_name ;
328 /****************/
330 SimplePDF::PDF_Vector::PDF_Vector( )
332 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c )
334 vec.push_back( SimplePDF::newFloat( c ) );
336 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1, PDF_Float::ValueType c2 )
338 vec.push_back( SimplePDF::newFloat( c1 ) );
339 vec.push_back( SimplePDF::newFloat( c2 ) );
341 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1, PDF_Float::ValueType c2, PDF_Float::ValueType c3 )
343 vec.push_back( SimplePDF::newFloat( c1 ) );
344 vec.push_back( SimplePDF::newFloat( c2 ) );
345 vec.push_back( SimplePDF::newFloat( c3 ) );
347 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType x1, PDF_Float::ValueType y1,
348 PDF_Float::ValueType x2, PDF_Float::ValueType y2 )
350 vec.push_back( SimplePDF::newFloat( x1 ) );
351 vec.push_back( SimplePDF::newFloat( y1 ) );
352 vec.push_back( SimplePDF::newFloat( x2 ) );
353 vec.push_back( SimplePDF::newFloat( y2 ) );
355 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType a, PDF_Float::ValueType b,
356 PDF_Float::ValueType c, PDF_Float::ValueType d,
357 PDF_Float::ValueType e, PDF_Float::ValueType f )
359 vec.push_back( SimplePDF::newFloat( a ) );
360 vec.push_back( SimplePDF::newFloat( b ) );
361 vec.push_back( SimplePDF::newFloat( c ) );
362 vec.push_back( SimplePDF::newFloat( d ) );
363 vec.push_back( SimplePDF::newFloat( e ) );
364 vec.push_back( SimplePDF::newFloat( f ) );
366 SimplePDF::PDF_Vector::PDF_Vector( PDF_Int::ValueType x1, PDF_Int::ValueType y1,
367 PDF_Int::ValueType x2, PDF_Int::ValueType y2 )
369 vec.push_back( SimplePDF::newInt( x1 ) );
370 vec.push_back( SimplePDF::newInt( y1 ) );
371 vec.push_back( SimplePDF::newInt( x2 ) );
372 vec.push_back( SimplePDF::newInt( y2 ) );
374 SimplePDF::PDF_Vector::~PDF_Vector( )
377 void
378 SimplePDF::PDF_Vector::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
380 os << "[" ;
381 for( VecType::const_iterator i( vec.begin( ) ); i != vec.end( ); ++i )
383 os << " " ;
384 (*i)->writeTo( os, xref, *i );
386 os << " ]" ;
389 RefCountPtr< PDF_Object >
390 SimplePDF::PDF_Vector::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
392 bool allSame( true );
393 RefCountPtr< PDF_Vector > res( new PDF_Vector );
394 res->vec.reserve( vec.size( ) );
395 for( VecType::iterator i( vec.begin( ) ); i != vec.end( ); ++i )
397 RefCountPtr< PDF_Object > copy( ::deepCopy( *i, indirectObjectCounter, remap ) );
398 res->vec.push_back( copy );
399 if( allSame && copy != *i )
401 allSame = false;
404 if( allSame )
406 return self;
408 return res;
411 RefCountPtr< SimplePDF::PDF_Vector >
412 SimplePDF::PDF_Vector::rectangleIntersection( const RefCountPtr< SimplePDF::PDF_Vector > & other ) const
414 if( vec.size( ) != 4 )
416 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
418 if( other->vec.size( ) != 4 )
420 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
423 RefCountPtr< PDF_Vector > res( new PDF_Vector );
424 res->vec.reserve( vec.size( ) );
426 typedef typeof vec VectorType;
427 typedef VectorType::const_iterator I;
428 I src1 = vec.begin( );
429 I src2 = other->vec.begin( );
430 res->vec.push_back( RefCountPtr< PDF_Float >( new PDF_Float( max( SimplePDF::down_cast_follow< PDF_Float >( *src1 )->value( ), SimplePDF::down_cast_follow< PDF_Float >( *src2 )->value( ) ) ) ) );
431 ++src1;
432 ++src2;
433 res->vec.push_back( RefCountPtr< PDF_Float >( new PDF_Float( max( SimplePDF::down_cast_follow< PDF_Float >( *src1 )->value( ), SimplePDF::down_cast_follow< PDF_Float >( *src2 )->value( ) ) ) ) );
434 ++src1;
435 ++src2;
436 res->vec.push_back( RefCountPtr< PDF_Float >( new PDF_Float( min( SimplePDF::down_cast_follow< PDF_Float >( *src1 )->value( ), SimplePDF::down_cast_follow< PDF_Float >( *src2 )->value( ) ) ) ) );
437 ++src1;
438 ++src2;
439 res->vec.push_back( RefCountPtr< PDF_Float >( new PDF_Float( min( SimplePDF::down_cast_follow< PDF_Float >( *src1 )->value( ), SimplePDF::down_cast_follow< PDF_Float >( *src2 )->value( ) ) ) ) );
441 return res;
445 /****************/
447 SimplePDF::PDF_Dictionary::PDF_Dictionary( )
449 SimplePDF::PDF_Dictionary::PDF_Dictionary( const PDF_Dictionary & orig )
450 : dic( orig.dic )
452 SimplePDF::PDF_Dictionary::~PDF_Dictionary( )
455 void
456 SimplePDF::PDF_Dictionary::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
458 os << "<< " ;
459 for( DicType::const_iterator i( dic.begin( ) ); i != dic.end( ); ++i )
461 os << "/" << (i->first) << " " ;
462 (i->second)->writeTo( os, xref, i->second );
463 os << endl ;
465 os << ">>" ;
468 void
469 SimplePDF::PDF_Dictionary::writeToWithLength( std::ostream & os, SimplePDF::PDF_xref * xref, size_t len ) const
471 os << "<< " ;
472 os << "/Length " << len << endl ;
473 for( DicType::const_iterator i( dic.begin( ) ); i != dic.end( ); ++i )
475 os << "/" << (i->first) << " " ;
476 (i->second)->writeTo( os, xref, i->second );
477 os << endl ;
479 os << ">>" ;
482 PDF_Int::ValueType
483 SimplePDF::PDF_Dictionary::getLength( ) const
485 DicType::const_iterator i( dic.find( string( "Length" ) ) );
486 if( i == dic.end( ) )
488 throw( "Dictionary[Length]: /Length field missing" );
490 RefCountPtr< const PDF_Int > theInt = SimplePDF::down_cast_follow< const PDF_Int >( i->second );
491 if( theInt == NullPtr< const PDF_Int >( ) )
493 throw( "Dictionary[Length]: /Length is not a PDF_Int" );
495 return theInt->value( );
498 PDF_Int::ValueType
499 SimplePDF::PDF_Dictionary::getCount( ) const
501 DicType::const_iterator i( dic.find( string( "Count" ) ) );
502 if( i == dic.end( ) )
504 throw( "Dictionary[Count]: /Count field missing" );
506 RefCountPtr< const PDF_Int > theInt = SimplePDF::down_cast_follow< const PDF_Int >( i->second );
507 if( theInt == NullPtr< const PDF_Int >( ) )
509 throw( "Dictionary[Count]: /Count is not a PDF_Int" );
511 return theInt->value( );
514 bool
515 SimplePDF::PDF_Dictionary::isPages( ) const
517 DicType::const_iterator i( dic.find( string( "Type" ) ) );
518 if( i == dic.end( ) )
520 throw( "PDF_Dictionary::isPages: /Type field missing" );
522 const PDF_Name * theType( dynamic_cast< const PDF_Name * >( i->second.getPtr( ) ) );
523 if( theType == 0 )
525 throw( "PDF_Dictionary::isPages: /Type is not a PDF_Name" );
527 return theType->name( ) == "Pages";
530 RefCountPtr< SimplePDF::PDF_Object >
531 SimplePDF::PDF_Dictionary::getInheritable( const char * name ) const
534 DicType::const_iterator i( dic.find( string( name ) ) );
535 if( i != dic.end( ) )
537 return i->second;
541 DicType::const_iterator i( dic.find( string( "Parent" ) ) );
542 if( i != dic.end( ) )
544 return SimplePDF::down_cast_follow< SimplePDF::PDF_Dictionary >( i->second )->getInheritable( name );
547 return RefCountPtr< SimplePDF::PDF_Object >( NullPtr< SimplePDF::PDF_Object >( ) );
551 RefCountPtr< PDF_Object > &
552 SimplePDF::PDF_Dictionary::operator [] ( const char * key )
554 DicType::iterator i( dic.find( key ) );
555 if( i == dic.end( ) )
557 return ((dic.insert(DicType::value_type( key, RefCountPtr< PDF_Object >( new PDF_Null( ) ) ))).first)->second;
559 return i->second;
562 bool
563 SimplePDF::PDF_Dictionary::hasKey( const char * key ) const
565 return dic.find( key ) != dic.end( );
568 RefCountPtr< PDF_Object >
569 SimplePDF::PDF_Dictionary::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
571 bool allSame( true );
572 RefCountPtr< PDF_Dictionary > res( new PDF_Dictionary );
573 for( DicType::iterator i( dic.begin( ) ); i != dic.end( ); ++i )
575 RefCountPtr< PDF_Object > copy( ::deepCopy( i->second, indirectObjectCounter, remap ) );
576 res->dic[ i->first ] = copy;
577 if( allSame && copy != i->second )
579 allSame = false;
582 if( allSame )
584 return self;
586 return res;
589 /****************/
591 SimplePDF::PDF_Stream::PDF_Stream( )
593 SimplePDF::PDF_Stream::PDF_Stream( const PDF_Dictionary & dic )
594 : PDF_Dictionary( dic )
596 SimplePDF::PDF_Stream::~PDF_Stream( )
599 void
600 SimplePDF::PDF_Stream::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
602 throw "PDF_Stream::writeTo called";
605 RefCountPtr< PDF_Object >
606 SimplePDF::PDF_Stream::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
608 throw "PDF_Stream::deepCopy must not be called. (However PDF_Stream_in::deepCopy may be called.)";
610 /****************/
612 SimplePDF::PDF_Stream_out::PDF_Stream_out( )
614 data << std::setiosflags( std::ios_base::fixed ) ;
616 SimplePDF::PDF_Stream_out::~PDF_Stream_out( )
619 void
620 SimplePDF::PDF_Stream_out::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
622 const string & dataStr( data.str( ) );
623 PDF_Dictionary::writeToWithLength( os, xref, dataStr.size( ) );
624 os << endl << "stream" << endl ;
625 os << dataStr << endl ;
626 os << "endstream " ;
629 /****************/
631 SimplePDF::PDF_Stream_in::PDF_Stream_in( PDF_Dictionary * dic, istream * _is, streamoff _dataStart )
632 : PDF_Stream( *dic ), is( _is ), dataStart( _dataStart )
634 SimplePDF::PDF_Stream_in::PDF_Stream_in( istream * _is, streamoff _dataStart )
635 : is( _is ), dataStart( _dataStart )
637 SimplePDF::PDF_Stream_in::~PDF_Stream_in( )
640 void
641 SimplePDF::PDF_Stream_in::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
643 size_t length( PDF_Dictionary::getLength( ) );
644 PDF_Dictionary::writeTo( os, xref, self );
645 os << endl << "stream" << endl ;
646 RefCountPtr< char > buf( new char[ length ] );
647 is->seekg( dataStart, ios::beg );
648 is->read( buf.getPtr( ), length );
649 os.write( buf.getPtr( ), length );
650 os << endl << "endstream " ;
652 void
653 SimplePDF::PDF_Stream_in::writeDataTo( std::ostream & os ) const
655 size_t length( PDF_Dictionary::getLength( ) );
656 RefCountPtr< char > buf( new char[ length ] );
657 is->seekg( dataStart, ios::beg );
658 is->read( buf.getPtr( ), length );
659 os.write( buf.getPtr( ), length );
661 void
662 SimplePDF::PDF_Stream_in::writeDataDefilteredTo( std::ostream & os ) const
664 if( dic.find( "Filter" ) == dic.end( ) )
666 writeDataTo( os );
667 return;
670 RefCountPtr< PDF_Object > filterEntry = RefCountPtr< PDF_Object >( new PDF_Null( ) );
671 typedef typeof dic DicType;
672 DicType::const_iterator i = dic.find( "Filter" );
673 if( i != dic.end( ) )
675 filterEntry = i->second;
677 if( filterEntry.down_cast< PDF_Null >( ) != NullPtr< PDF_Null >( ) )
679 writeDataTo( os );
680 return;
683 RefCountPtr< PDF_Name > filterNameObj( filterEntry.down_cast< PDF_Name >( ) );
684 if( filterNameObj == NullPtr< PDF_Name >( ) )
686 throw( "The Filter entry was not a name (nor null) in the stream dictionary" );
688 const string & filter( filterNameObj->name( ) );
690 if( filter == "FlateDecode" )
692 size_t inBufSize( PDF_Dictionary::getLength( ) );
693 RefCountPtr< char > inBuf( new char[ inBufSize ] );
694 is->seekg( dataStart, ios::beg );
695 is->read( inBuf.getPtr( ), inBufSize );
697 const size_t BUFSIZE( 1024 );
698 RefCountPtr< char > outBuf( new char[ BUFSIZE ] );
700 z_stream zs;
701 zs.next_in = reinterpret_cast< Bytef * >( inBuf.getPtr( ) );
702 zs.avail_in = inBufSize;
703 zs.next_out = reinterpret_cast< Bytef * >( outBuf.getPtr( ) );
704 zs.avail_out = BUFSIZE;
705 zs.zalloc = Z_NULL;
706 zs.zfree = Z_NULL;
707 switch( inflateInit( & zs ) )
709 case Z_OK:
710 break;
711 default:
712 throw( "inflateInit failed" );
716 int status;
717 while( ( status = inflate( & zs, Z_NO_FLUSH ) ) == Z_OK )
719 os.write( outBuf.getPtr( ), BUFSIZE - zs.avail_out );
720 zs.next_out = reinterpret_cast< Bytef * >( outBuf.getPtr( ) );
721 zs.avail_out = BUFSIZE;
723 switch( status )
725 case Z_STREAM_END:
726 os.write( outBuf.getPtr( ), BUFSIZE - zs.avail_out );
727 break;
728 default:
729 throw( "The inflate cycle did not finish with Z_STREAM_END" );
733 switch( inflateEnd( & zs ) )
735 case Z_OK:
736 break;
737 default:
738 throw( "inflateEnd failed" );
741 else
743 throw( "The filter " + filter + " is not yet supported" );
747 RefCountPtr< PDF_Object >
748 SimplePDF::PDF_Stream_in::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
750 RefCountPtr< PDF_Object > dicCopy( PDF_Dictionary::deepCopy( self, indirectObjectCounter, remap ) );
751 if( dicCopy.getPtr( ) == this )
753 return self;
755 /* By increasing the count by 1, we ensure that the memory is not destroyed when this function exits.
756 * We use that this object is newly created, so there are no other references to it.
758 if( *dicCopy.getCounterPtr( ) != 1 )
760 throw "I expected to own the only reference to the new PDF_Dictionary";
762 ++(*dicCopy.getCounterPtr( ));
763 return RefCountPtr< PDF_Stream_in >( new PDF_Stream_in( reinterpret_cast< PDF_Dictionary * >( dicCopy.getPtr( ) ), is, dataStart ) );
765 /****************/
767 SimplePDF::PDF_Indirect::PDF_Indirect( size_t _i, size_t _v )
768 : i( _i ), v( _v )
770 SimplePDF::PDF_Indirect::~PDF_Indirect( )
772 void
773 SimplePDF::PDF_Indirect_in::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
775 throw "Internal error: PDF_Indirect_in::writeTo: This object is only good for reading, not for writing!";
776 // os << i << " " << v << " R" ;
778 bool SimplePDF::operator < ( const PDF_Indirect & o1, const PDF_Indirect & o2 )
780 if( o1.i < o2.i )
782 return true;
784 if( o1.i > o2.i )
786 return false;
788 if( o1.v < o2.v )
790 return true;
792 return false;
794 RefCountPtr< PDF_Object >
795 SimplePDF::PDF_Indirect::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
797 throw "PDF_Indirect::deepCopy must not be called. (However PDF_Indirect_in::deepCopy may be called.)";
799 /****************/
801 SimplePDF::PDF_Indirect_out::PDF_Indirect_out( RefCountPtr<PDF_Object> _obj, size_t _i, size_t _v )
802 : PDF_Indirect( _i, _v ), inUse( true ), obj( _obj )
804 SimplePDF::PDF_Indirect_out::~PDF_Indirect_out( )
806 void
807 SimplePDF::PDF_Indirect_out::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
809 xref->enqueue( self.down_cast< const PDF_Indirect_out >( ) ); /* This shall not fail! */
810 os << xref->local( i ) << " " << v << " R" ; /* We must not call xref->local before xref->enqueue ! */
812 void
813 SimplePDF::PDF_Indirect_out::writeObject( std::ostream & os, SimplePDF::PDF_xref * xref ) const
815 if( inUse )
817 os << xref->local( i ) << " " << v << " obj" << endl ;
818 obj->writeTo( os, xref, obj );
819 os << endl << "endobj" << endl ;
823 /****************/
825 SimplePDF::PDF_Indirect_in::PDF_Indirect_in( size_t _i, size_t _v )
826 : PDF_Indirect( _i, _v ), PDFin( 0 )
828 SimplePDF::PDF_Indirect_in::~PDF_Indirect_in( )
830 RefCountPtr< PDF_Object >
831 SimplePDF::PDF_Indirect_in::deref( )
833 if( PDFin == 0 )
835 throw( "PDF_Indirect_in::deref: PDFin is not assigned" );
837 return PDFin->readObjectNumbered( i, v );
839 RefCountPtr< PDF_Object >
840 SimplePDF::PDF_Indirect_in::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
843 IndirectRemapType::iterator i( remap->find( *this ) );
844 if( i != remap->end( ) )
846 return i->second;
849 return remap->insert( IndirectRemapType::value_type( *this, SimplePDF::indirect( ::deepCopy( deref( ), indirectObjectCounter, remap ),
850 indirectObjectCounter ) ) ).first->second;
853 /**************/
855 SimplePDF::PDF_xref::PDF_xref( )
856 : size_( 0 )
858 /* The first position in the xref table is special. */
859 localOrder_.push_back( 0 ); /* The first object shall appear in the xref table. */
860 localNumbers_.push_back( 0 ); /* It has number 0. */
861 byteOffsets_.push_back( 0 ); /* This is interpreted as "not in use" */
862 generations_.push_back( 65535 );
865 void
866 SimplePDF::PDF_xref::enqueue( const RefCountPtr< const::PDF_Indirect_out > & obj )
868 /* Grow big enough */
869 while( byteOffsets_.size( ) <= obj->i )
871 localNumbers_.push_back( 0 );
872 byteOffsets_.push_back( 0 );
873 generations_.push_back( 0 );
876 if( byteOffsets_[ obj->i ] == 0 )
878 indirectQueue_.push_back( obj );
879 localNumbers_[ obj->i ] = localOrder_.size( );
880 byteOffsets_[ obj->i ] = 1; /* We will change this later, this just indicates that the object has been put in queue. */
881 localOrder_.push_back( obj->i );
885 void
886 SimplePDF::PDF_xref::writeRecursive( std::ostream & os )
888 std::streamoff os_start;
890 std::streamoff tmp = static_cast< streamoff >( os.tellp( ) );
891 os.seekp( 0 );
892 os_start = static_cast< streamoff >( os.tellp( ) ); /* Will this always be some kind of zero value? */
893 os.seekp( tmp );
895 while( ! indirectQueue_.empty( ) )
897 RefCountPtr< const SimplePDF::PDF_Indirect_out > i_obj = indirectQueue_.front( );
898 indirectQueue_.pop_front( );
899 byteOffsets_[ i_obj->i ] = static_cast< streamoff >( os.tellp( ) ) - os_start;
900 generations_[ i_obj->i ] = i_obj->v;
901 i_obj->writeObject( os, this );
905 size_t
906 SimplePDF::PDF_xref::local( size_t i ) const
908 return localNumbers_[ i ];
911 void
912 SimplePDF::PDF_xref::writeTable( std::ostream & os ) const
914 if( size_ > 0 )
916 throw "Internal error: PDF_xref::writeTable: This table has already been written.";
918 size_ = localOrder_.size( );
920 os << setfill( '0' ) ;
921 os << "xref" << endl
922 << 0 << " " << size_ << endl ;
923 typedef typeof localOrder_ ListType;
924 for( ListType::const_iterator i = localOrder_.begin( ); i != localOrder_.end( ); ++i )
926 size_t v = generations_[ *i ];
927 size_t o = byteOffsets_[ *i ];
928 os << setw( 10 ) << o << ' ' << setw( 5 ) << v << ' ' << 'n' << ' ' << static_cast< char >( 10 ) ;
932 size_t
933 SimplePDF::PDF_xref::size( ) const
935 if( size_ == 0 )
937 throw "Internal error: PDF_xref::size: The size of the table is not determined yet. Call writeTable first.";
939 return size_;
943 /**************/
945 RefCountPtr< PDF_Indirect_out >
946 SimplePDF::indirect( RefCountPtr< PDF_Object > obj, size_t * i, size_t v )
948 return RefCountPtr< PDF_Indirect_out >( new PDF_Indirect_out( obj, (*i)++, v ) );
951 RefCountPtr< PDF_Object >
952 SimplePDF::deepCopy( RefCountPtr< PDF_Object > obj, size_t * indirectObjectCounter, IndirectRemapType * remap )
954 return obj->deepCopy( obj, indirectObjectCounter, remap );