Update procedures
[shapes.git] / source / pdfstructure.cc
blob72b7d4b5d95c29b67e672e16bb05e0bd79b0202f
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 "check.h"
29 #include "autoonoff.h"
31 using namespace std;
33 using namespace SimplePDF;
35 /****************/
37 SimplePDF::PDF_Object::PDF_Object( )
38 : complete( false )
39 { }
40 SimplePDF::PDF_Object::~PDF_Object( )
41 { }
42 void
43 SimplePDF::PDF_Object::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
45 throw "This function, PDF_Object::writeTo, must not be called. It is practically purely virtual.";
47 RefCountPtr< PDF_Object >
48 SimplePDF::PDF_Object::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
50 return self;
53 /****************/
55 template< class S >
56 RefCountPtr< S >
57 SimplePDF::down_cast_follow( RefCountPtr< PDF_Object > maybeIndirect )
60 const PDF_Indirect_in * theIndirect( dynamic_cast< const PDF_Indirect_in * >( maybeIndirect.getPtr( ) ) );
61 if( theIndirect != 0 )
63 return theIndirect->PDFin->follow< S >( maybeIndirect );
67 const PDF_Indirect_out * theIndirect( dynamic_cast< const PDF_Indirect_out * >( maybeIndirect.getPtr( ) ) );
68 if( theIndirect != 0 )
70 return SimplePDF::down_cast_follow< S >( theIndirect->obj );
74 return maybeIndirect.down_cast< S >( );
77 namespace SimplePDF
79 template< >
80 RefCountPtr< SimplePDF::PDF_Float >
81 down_cast_follow< SimplePDF::PDF_Float >( RefCountPtr< PDF_Object > maybeIndirect )
84 const PDF_Indirect_in * theIndirect( dynamic_cast< const PDF_Indirect_in * >( maybeIndirect.getPtr( ) ) );
85 if( theIndirect != 0 )
87 return theIndirect->PDFin->follow< SimplePDF::PDF_Float >( maybeIndirect );
91 const PDF_Indirect_out * theIndirect( dynamic_cast< const PDF_Indirect_out * >( maybeIndirect.getPtr( ) ) );
92 if( theIndirect != 0 )
94 return SimplePDF::down_cast_follow< SimplePDF::PDF_Float >( theIndirect->obj );
98 RefCountPtr< PDF_Int > res( maybeIndirect.down_cast< PDF_Int >( ) );
99 if( res != NullPtr< PDF_Int >( ) )
101 return RefCountPtr< PDF_Float >( new PDF_Float( res->value( ) ) );
104 return maybeIndirect.down_cast< SimplePDF::PDF_Float >( );
108 namespace SimplePDF
110 template RefCountPtr< SimplePDF::PDF_Vector > down_cast_follow< SimplePDF::PDF_Vector >( RefCountPtr< PDF_Object > );
113 /****************/
115 SimplePDF::PDF_Null::PDF_Null( )
117 SimplePDF::PDF_Null::~PDF_Null( )
120 void
121 SimplePDF::PDF_Null::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
123 os << "null" ;
126 /****************/
128 SimplePDF::PDF_Boolean::PDF_Boolean( ValueType _value )
129 : my_value( _value )
131 SimplePDF::PDF_Boolean::~PDF_Boolean( )
134 SimplePDF::PDF_Boolean::ValueType
135 SimplePDF::PDF_Boolean::value( ) const
137 return my_value;
140 void
141 SimplePDF::PDF_Boolean::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
143 if( my_value )
145 os << "true" ;
147 else
149 os << "false" ;
153 /****************/
155 SimplePDF::PDF_Int::PDF_Int( PDF_Int::ValueType _value )
156 : my_value( _value )
158 SimplePDF::PDF_Int::PDF_Int( const char * strvalue )
160 /* How can it be that end shall be non-const, while strvalue is const? */
161 // const char * end;
162 char * end;
163 my_value = strtol( strvalue, & end, 10 );
164 if( *end != '\0' )
166 throw "Internal error: Bad numeric int format";
169 SimplePDF::PDF_Int::~PDF_Int( )
172 PDF_Int::ValueType
173 SimplePDF::PDF_Int::value( ) const
175 return my_value;
178 void
179 SimplePDF::PDF_Int::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
181 os << my_value ;
184 /****************/
186 SimplePDF::PDF_Float::PDF_Float( PDF_Float::ValueType _value )
187 : my_value( _value )
189 SimplePDF::PDF_Float::PDF_Float( const char * strvalue )
191 /* How can it be that end shall be non-const, while strvalue is const? */
192 // const char * end;
193 char * end;
194 my_value = strtod( strvalue, & end );
195 if( *end != '\0' )
197 throw( "Internal error: Bad numeric float format" );
200 SimplePDF::PDF_Float::~PDF_Float( )
203 SimplePDF::PDF_Float::ValueType PDF_Float::value( ) const
205 return my_value;
208 void
209 SimplePDF::PDF_Float::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
211 os << my_value ;
214 /****************/
216 SimplePDF::PDF_String::PDF_String( )
218 SimplePDF::PDF_String::~PDF_String( )
221 /****************/
223 SimplePDF::PDF_LiteralString::PDF_LiteralString( const string & _str )
224 : my_str( _str )
226 SimplePDF::PDF_LiteralString::PDF_LiteralString( const char * _str )
227 : my_str( _str )
229 SimplePDF::PDF_LiteralString::PDF_LiteralString( const list< RefCountPtr< char > > & strs )
231 size_t length( 0 );
232 typedef list< RefCountPtr< char > >::const_iterator I;
233 for( I i( strs.begin( ) ); i != strs.end( ); ++i )
235 length += strlen( i->getPtr( ) );
237 RefCountPtr< char > mem( new char[ length + 1 ] );
238 char * dst = mem.getPtr( );
239 for( I i( strs.begin( ) ); i != strs.end( ); ++i )
241 strcpy( dst, i->getPtr( ) );
242 dst += strlen( i->getPtr( ) );
244 *dst = '\0';
245 my_str = mem.getPtr( );
247 SimplePDF::PDF_LiteralString::~PDF_LiteralString( )
250 const string &
251 SimplePDF::PDF_LiteralString::str( ) const
253 return my_str;
256 void
257 SimplePDF::PDF_LiteralString::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
259 os << "(" ;
260 for( const char * src = my_str.c_str( ); *src != '\0'; ++src )
262 switch( *src )
264 case '(':
265 os << "\\(" ;
266 break;
267 case ')':
268 os << "\\)" ;
269 break;
270 case '\\':
271 os << "\\\\" ;
272 break;
273 default:
274 os << *src ;
277 os << ")" ;
280 /****************/
282 SimplePDF::PDF_HexString::PDF_HexString( const string & _hexstr )
283 : my_hexstr( _hexstr )
285 SimplePDF::PDF_HexString::PDF_HexString( const char * _hexstr )
286 : my_hexstr( _hexstr )
288 SimplePDF::PDF_HexString::~PDF_HexString( )
291 const string &
292 SimplePDF::PDF_HexString::hexstr( ) const
294 return my_hexstr;
297 void
298 SimplePDF::PDF_HexString::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
300 os << "<" << my_hexstr << ">" ;
303 /****************/
305 SimplePDF::PDF_Name::PDF_Name( const string & _name )
306 : my_name( _name )
308 SimplePDF::PDF_Name::~PDF_Name( )
311 const string &
312 SimplePDF::PDF_Name::name( ) const
314 return my_name;
317 void
318 SimplePDF::PDF_Name::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
320 os << "/" << my_name ;
323 ostream & SimplePDF::operator << ( std::ostream & os, const PDF_Name & self )
325 return os << "/" << self.my_name ;
329 /****************/
331 SimplePDF::PDF_Vector::PDF_Vector( )
333 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c )
335 vec.push_back( SimplePDF::newFloat( c ) );
337 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1, PDF_Float::ValueType c2 )
339 vec.push_back( SimplePDF::newFloat( c1 ) );
340 vec.push_back( SimplePDF::newFloat( c2 ) );
342 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType c1, PDF_Float::ValueType c2, PDF_Float::ValueType c3 )
344 vec.push_back( SimplePDF::newFloat( c1 ) );
345 vec.push_back( SimplePDF::newFloat( c2 ) );
346 vec.push_back( SimplePDF::newFloat( c3 ) );
348 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType x1, PDF_Float::ValueType y1,
349 PDF_Float::ValueType x2, PDF_Float::ValueType y2 )
351 vec.push_back( SimplePDF::newFloat( x1 ) );
352 vec.push_back( SimplePDF::newFloat( y1 ) );
353 vec.push_back( SimplePDF::newFloat( x2 ) );
354 vec.push_back( SimplePDF::newFloat( y2 ) );
356 SimplePDF::PDF_Vector::PDF_Vector( PDF_Float::ValueType a, PDF_Float::ValueType b,
357 PDF_Float::ValueType c, PDF_Float::ValueType d,
358 PDF_Float::ValueType e, PDF_Float::ValueType f )
360 vec.push_back( SimplePDF::newFloat( a ) );
361 vec.push_back( SimplePDF::newFloat( b ) );
362 vec.push_back( SimplePDF::newFloat( c ) );
363 vec.push_back( SimplePDF::newFloat( d ) );
364 vec.push_back( SimplePDF::newFloat( e ) );
365 vec.push_back( SimplePDF::newFloat( f ) );
367 SimplePDF::PDF_Vector::PDF_Vector( PDF_Int::ValueType x1, PDF_Int::ValueType y1,
368 PDF_Int::ValueType x2, PDF_Int::ValueType y2 )
370 vec.push_back( SimplePDF::newInt( x1 ) );
371 vec.push_back( SimplePDF::newInt( y1 ) );
372 vec.push_back( SimplePDF::newInt( x2 ) );
373 vec.push_back( SimplePDF::newInt( y2 ) );
375 SimplePDF::PDF_Vector::~PDF_Vector( )
378 void
379 SimplePDF::PDF_Vector::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
381 os << "[" ;
382 for( VecType::const_iterator i( vec.begin( ) ); i != vec.end( ); ++i )
384 os << " " ;
385 (*i)->writeTo( os, xref, *i );
387 os << " ]" ;
390 RefCountPtr< PDF_Object >
391 SimplePDF::PDF_Vector::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
393 bool allSame( true );
394 RefCountPtr< PDF_Vector > res( new PDF_Vector );
395 res->vec.reserve( vec.size( ) );
396 for( VecType::iterator i( vec.begin( ) ); i != vec.end( ); ++i )
398 RefCountPtr< PDF_Object > copy( ::deepCopy( *i, indirectObjectCounter, remap ) );
399 res->vec.push_back( copy );
400 if( allSame && copy != *i )
402 allSame = false;
405 if( allSame )
407 return self;
409 return res;
412 RefCountPtr< SimplePDF::PDF_Vector >
413 SimplePDF::PDF_Vector::rectangleIntersection( const RefCountPtr< SimplePDF::PDF_Vector > & other ) const
415 if( vec.size( ) != 4 )
417 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
419 if( other->vec.size( ) != 4 )
421 throw "Internal error: PDF_Vector::rectangleIntersection: self size is not 4.";
424 RefCountPtr< PDF_Vector > res( new PDF_Vector );
425 res->vec.reserve( vec.size( ) );
427 typedef typeof vec VectorType;
428 typedef VectorType::const_iterator I;
429 I src1 = vec.begin( );
430 I src2 = other->vec.begin( );
431 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( ) ) ) ) );
432 ++src1;
433 ++src2;
434 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( ) ) ) ) );
435 ++src1;
436 ++src2;
437 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( ) ) ) ) );
438 ++src1;
439 ++src2;
440 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( ) ) ) ) );
442 return res;
446 /****************/
448 SimplePDF::PDF_Dictionary::PDF_Dictionary( )
450 SimplePDF::PDF_Dictionary::PDF_Dictionary( const PDF_Dictionary & orig )
451 : dic( orig.dic )
453 SimplePDF::PDF_Dictionary::~PDF_Dictionary( )
456 void
457 SimplePDF::PDF_Dictionary::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
459 os << "<< " ;
460 for( DicType::const_iterator i( dic.begin( ) ); i != dic.end( ); ++i )
462 os << "/" << (i->first) << " " ;
463 (i->second)->writeTo( os, xref, i->second );
464 os << endl ;
466 os << ">>" ;
469 void
470 SimplePDF::PDF_Dictionary::writeToWithLength( std::ostream & os, SimplePDF::PDF_xref * xref, size_t len ) const
472 os << "<< " ;
473 os << "/Length " << len << endl ;
474 for( DicType::const_iterator i( dic.begin( ) ); i != dic.end( ); ++i )
476 os << "/" << (i->first) << " " ;
477 (i->second)->writeTo( os, xref, i->second );
478 os << endl ;
480 os << ">>" ;
483 PDF_Int::ValueType
484 SimplePDF::PDF_Dictionary::getLength( ) const
486 DicType::const_iterator i( dic.find( string( "Length" ) ) );
487 if( i == dic.end( ) )
489 throw( "Dictionary[Length]: /Length field missing" );
491 RefCountPtr< const PDF_Int > theInt = SimplePDF::down_cast_follow< const PDF_Int >( i->second );
492 if( theInt == NullPtr< const PDF_Int >( ) )
494 throw( "Dictionary[Length]: /Length is not a PDF_Int" );
496 return theInt->value( );
499 PDF_Int::ValueType
500 SimplePDF::PDF_Dictionary::getCount( ) const
502 DicType::const_iterator i( dic.find( string( "Count" ) ) );
503 if( i == dic.end( ) )
505 throw( "Dictionary[Count]: /Count field missing" );
507 RefCountPtr< const PDF_Int > theInt = SimplePDF::down_cast_follow< const PDF_Int >( i->second );
508 if( theInt == NullPtr< const PDF_Int >( ) )
510 throw( "Dictionary[Count]: /Count is not a PDF_Int" );
512 return theInt->value( );
515 bool
516 SimplePDF::PDF_Dictionary::isPages( ) const
518 DicType::const_iterator i( dic.find( string( "Type" ) ) );
519 if( i == dic.end( ) )
521 throw( "PDF_Dictionary::isPages: /Type field missing" );
523 const PDF_Name * theType( dynamic_cast< const PDF_Name * >( i->second.getPtr( ) ) );
524 if( theType == 0 )
526 throw( "PDF_Dictionary::isPages: /Type is not a PDF_Name" );
528 return theType->name( ) == "Pages";
531 RefCountPtr< SimplePDF::PDF_Object >
532 SimplePDF::PDF_Dictionary::getInheritable( const char * name ) const
535 DicType::const_iterator i( dic.find( string( name ) ) );
536 if( i != dic.end( ) )
538 return i->second;
542 DicType::const_iterator i( dic.find( string( "Parent" ) ) );
543 if( i != dic.end( ) )
545 return SimplePDF::down_cast_follow< SimplePDF::PDF_Dictionary >( i->second )->getInheritable( name );
548 return RefCountPtr< SimplePDF::PDF_Object >( NullPtr< SimplePDF::PDF_Object >( ) );
552 RefCountPtr< PDF_Object > &
553 SimplePDF::PDF_Dictionary::operator [] ( const char * key )
555 DicType::iterator i( dic.find( key ) );
556 if( i == dic.end( ) )
558 return ((dic.insert(DicType::value_type( key, RefCountPtr< PDF_Object >( new PDF_Null( ) ) ))).first)->second;
560 return i->second;
563 bool
564 SimplePDF::PDF_Dictionary::hasKey( const char * key ) const
566 return dic.find( key ) != dic.end( );
569 RefCountPtr< PDF_Object >
570 SimplePDF::PDF_Dictionary::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
572 bool allSame( true );
573 RefCountPtr< PDF_Dictionary > res( new PDF_Dictionary );
574 for( DicType::iterator i( dic.begin( ) ); i != dic.end( ); ++i )
576 RefCountPtr< PDF_Object > copy( ::deepCopy( i->second, indirectObjectCounter, remap ) );
577 res->dic[ i->first ] = copy;
578 if( allSame && copy != i->second )
580 allSame = false;
583 if( allSame )
585 return self;
587 return res;
590 /****************/
592 SimplePDF::PDF_Stream::PDF_Stream( )
594 SimplePDF::PDF_Stream::PDF_Stream( const PDF_Dictionary & dic )
595 : PDF_Dictionary( dic )
597 SimplePDF::PDF_Stream::~PDF_Stream( )
600 void
601 SimplePDF::PDF_Stream::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
603 throw "PDF_Stream::writeTo called";
606 RefCountPtr< PDF_Object >
607 SimplePDF::PDF_Stream::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
609 throw "PDF_Stream::deepCopy must not be called. (However PDF_Stream_in::deepCopy may be called.)";
612 PDF_Int::ValueType
613 SimplePDF::PDF_Stream::getPredictor( ) const
615 PDF_Int::ValueType predictor = 1;
616 DicType::const_iterator i = dic.find( "Predictor" );
617 if( i != dic.end( ) )
619 RefCountPtr< PDF_Int > predictorIntObj( i->second.down_cast< PDF_Int >( ) );
620 if( predictorIntObj == NullPtr< PDF_Int >( ) )
622 throw( "The Predictor entry was not an integer (nor null) in the stream dictionary" );
624 predictor = predictorIntObj->value( );
626 return predictor;
629 /****************/
631 SimplePDF::PDF_Stream_out::PDF_Stream_out( )
632 : invertFilterOnWrite( true )
634 data << std::setiosflags( std::ios_base::fixed ) ;
636 SimplePDF::PDF_Stream_out::~PDF_Stream_out( )
639 void
640 SimplePDF::PDF_Stream_out::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
642 RefCountPtr< PDF_Object > filterEntry = RefCountPtr< PDF_Object >( new PDF_Null( ) );
643 typedef typeof dic DicType;
644 DicType::const_iterator i = dic.find( "Filter" );
645 if( i == dic.end( ) || ! invertFilterOnWrite )
647 goto writeStream_NoFilter;
649 else
651 filterEntry = i->second;
653 if( filterEntry.down_cast< PDF_Null >( ) != NullPtr< PDF_Null >( ) )
655 goto writeStream_NoFilter;
659 RefCountPtr< PDF_Name > filterNameObj( filterEntry.down_cast< PDF_Name >( ) );
660 if( filterNameObj == NullPtr< PDF_Name >( ) )
662 throw( "The Filter entry was not a name (nor null) in the stream dictionary." );
664 const string & filter( filterNameObj->name( ) );
666 std::ostringstream stream;
667 if( filter == "FlateDecode" )
669 writeStream_FlateDecode( stream );
671 else
673 throw( "The Filter entry was not recognized: " + filter );
677 const string & dataStr( stream.str( ) );
678 PDF_Dictionary::writeToWithLength( os, xref, dataStr.size( ) );
679 os << endl << "stream" << endl ;
680 os << dataStr << endl ;
681 os << "endstream " ;
684 return;
686 writeStream_NoFilter:
688 const string & dataStr( data.str( ) );
689 PDF_Dictionary::writeToWithLength( os, xref, dataStr.size( ) );
690 os << endl << "stream" << endl ;
691 os << dataStr << endl ;
692 os << "endstream " ;
696 class Auto_zlib_deflateEnd
698 z_stream * strm_;
699 public:
700 Auto_zlib_deflateEnd( z_stream * strm )
701 : strm_( strm )
703 ~Auto_zlib_deflateEnd( )
705 deflateEnd( strm_ );
709 void
710 SimplePDF::PDF_Stream_out::writeStream_FlateDecode( std::ostream & stream ) const
712 if( getPredictor( ) != 1 )
714 throw( "The only supported Predictor for FlateDecode compression is 1." );
717 const size_t BUFSIZE( 16384 );
718 RefCountPtr< char > outBuf( new char[ BUFSIZE ] );
720 /* The following code follows the example in the zlib documentation rather closely. */
722 int ret, flush;
723 size_t have;
724 z_stream strm;
725 Auto_zlib_deflateEnd autoDeflateEnd( & strm ); // Deallocate strm when we are done.
726 unsigned char in[ BUFSIZE ];
727 unsigned char out[ BUFSIZE ];
729 const int LEVEL = Z_DEFAULT_COMPRESSION;
730 /* Alternative compression levels: */
731 // Z_BEST_SPEED
732 // Z_BEST_COMPRESSION
733 // Z_DEFAULT_COMPRESSION
735 /* allocate deflate state */
736 strm.zalloc = Z_NULL;
737 strm.zfree = Z_NULL;
738 strm.opaque = Z_NULL;
739 ret = deflateInit( & strm, LEVEL );
740 if( ret != Z_OK )
742 throw( std::string( "zlib call failed: " ) + zError( ret ) );
745 istringstream source( data.str( ) );
749 source.read( reinterpret_cast< char * >( in ), BUFSIZE );
750 strm.avail_in = source.gcount( );
751 if( ! source.good( ) && ! source.eof( ) )
753 throw( "Failed to read from data stream being FlateDecode compressed." );
755 flush = source.eof( ) ? Z_FINISH : Z_NO_FLUSH;
756 strm.next_in = in;
758 /* run deflate() on input until output buffer not full, finish
759 compression if all of source has been read in */
762 strm.avail_out = BUFSIZE;
763 strm.next_out = out;
764 ret = deflate( & strm, flush ); /* no bad return value */
765 CHECK( if( ret == Z_STREAM_ERROR )
767 throw( std::string( "zlib deflate call failed with Z_STREAM_ERROR: " ) + zError( ret ) );
771 have = BUFSIZE - strm.avail_out;
772 stream.write( reinterpret_cast< const char * >( out ), have ); /* It could be a good idea to check if this operation was successful... */
774 while( strm.avail_out == 0 );
775 CHECK( if( strm.avail_in != 0 )
777 throw( std::string( "FlateDecode compression failed to consume all input." ) );
781 /* done when last data in file processed */
783 while( flush != Z_FINISH );
784 CHECK( if( ret != Z_STREAM_END )
786 throw( std::string( "FlateDecode compression failed to complete zlib stream." ) );
791 /****************/
793 SimplePDF::PDF_Stream_in::PDF_Stream_in( PDF_Dictionary * dic, istream * _is, streamoff _dataStart )
794 : PDF_Stream( *dic ), is( _is ), dataStart( _dataStart )
796 SimplePDF::PDF_Stream_in::PDF_Stream_in( istream * _is, streamoff _dataStart )
797 : is( _is ), dataStart( _dataStart )
799 SimplePDF::PDF_Stream_in::~PDF_Stream_in( )
802 void
803 SimplePDF::PDF_Stream_in::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
805 size_t length( PDF_Dictionary::getLength( ) );
806 PDF_Dictionary::writeTo( os, xref, self );
807 os << endl << "stream" << endl ;
808 RefCountPtr< char > buf( new char[ length ] );
809 is->seekg( dataStart, ios::beg );
810 is->read( buf.getPtr( ), length );
811 os.write( buf.getPtr( ), length );
812 os << endl << "endstream " ;
814 void
815 SimplePDF::PDF_Stream_in::writeDataTo( std::ostream & os ) const
817 size_t length( PDF_Dictionary::getLength( ) );
818 RefCountPtr< char > buf( new char[ length ] );
819 is->seekg( dataStart, ios::beg );
820 is->read( buf.getPtr( ), length );
821 os.write( buf.getPtr( ), length );
823 void
824 SimplePDF::PDF_Stream_in::writeDataDefilteredTo( std::ostream & os ) const
826 if( dic.find( "Filter" ) == dic.end( ) )
828 writeDataTo( os );
829 return;
832 RefCountPtr< PDF_Object > filterEntry = RefCountPtr< PDF_Object >( new PDF_Null( ) );
833 typedef typeof dic DicType;
834 DicType::const_iterator i = dic.find( "Filter" );
835 if( i != dic.end( ) )
837 filterEntry = i->second;
839 if( filterEntry.down_cast< PDF_Null >( ) != NullPtr< PDF_Null >( ) )
841 writeDataTo( os );
842 return;
845 RefCountPtr< PDF_Name > filterNameObj( filterEntry.down_cast< PDF_Name >( ) );
846 if( filterNameObj == NullPtr< PDF_Name >( ) )
848 throw( "The Filter entry was not a name (nor null) in the stream dictionary" );
850 const string & filter( filterNameObj->name( ) );
852 if( filter == "FlateDecode" )
854 if( getPredictor( ) != 1 )
856 throw( "The only supported Predictor for FlateDecode decompression is 1." );
859 size_t inBufSize( PDF_Dictionary::getLength( ) );
860 RefCountPtr< char > inBuf( new char[ inBufSize ] );
861 is->seekg( dataStart, ios::beg );
862 is->read( inBuf.getPtr( ), inBufSize );
864 const size_t BUFSIZE( 1024 );
865 RefCountPtr< char > outBuf( new char[ BUFSIZE ] );
867 z_stream zs;
868 zs.next_in = reinterpret_cast< Bytef * >( inBuf.getPtr( ) );
869 zs.avail_in = inBufSize;
870 zs.next_out = reinterpret_cast< Bytef * >( outBuf.getPtr( ) );
871 zs.avail_out = BUFSIZE;
872 zs.zalloc = Z_NULL;
873 zs.zfree = Z_NULL;
874 switch( inflateInit( & zs ) )
876 case Z_OK:
877 break;
878 default:
879 throw( "inflateInit failed" );
883 int status;
884 while( ( status = inflate( & zs, Z_NO_FLUSH ) ) == Z_OK )
886 os.write( outBuf.getPtr( ), BUFSIZE - zs.avail_out );
887 zs.next_out = reinterpret_cast< Bytef * >( outBuf.getPtr( ) );
888 zs.avail_out = BUFSIZE;
890 switch( status )
892 case Z_STREAM_END:
893 os.write( outBuf.getPtr( ), BUFSIZE - zs.avail_out );
894 break;
895 default:
896 throw( "The inflate cycle did not finish with Z_STREAM_END" );
900 switch( inflateEnd( & zs ) )
902 case Z_OK:
903 break;
904 default:
905 throw( "inflateEnd failed" );
908 else
910 throw( "The filter " + filter + " is not yet supported" );
914 RefCountPtr< PDF_Object >
915 SimplePDF::PDF_Stream_in::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
917 RefCountPtr< PDF_Object > dicCopy( PDF_Dictionary::deepCopy( self, indirectObjectCounter, remap ) );
918 if( dicCopy.getPtr( ) == this )
920 return self;
922 /* By increasing the count by 1, we ensure that the memory is not destroyed when this function exits.
923 * We use that this object is newly created, so there are no other references to it.
925 if( *dicCopy.getCounterPtr( ) != 1 )
927 throw "I expected to own the only reference to the new PDF_Dictionary";
929 ++(*dicCopy.getCounterPtr( ));
930 return RefCountPtr< PDF_Stream_in >( new PDF_Stream_in( reinterpret_cast< PDF_Dictionary * >( dicCopy.getPtr( ) ), is, dataStart ) );
932 /****************/
934 SimplePDF::PDF_Indirect::PDF_Indirect( size_t _i, size_t _v )
935 : i( _i ), v( _v )
937 SimplePDF::PDF_Indirect::~PDF_Indirect( )
939 void
940 SimplePDF::PDF_Indirect_in::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
942 throw "Internal error: PDF_Indirect_in::writeTo: This object is only good for reading, not for writing!";
943 // os << i << " " << v << " R" ;
945 bool SimplePDF::operator < ( const PDF_Indirect & o1, const PDF_Indirect & o2 )
947 if( o1.i < o2.i )
949 return true;
951 if( o1.i > o2.i )
953 return false;
955 if( o1.v < o2.v )
957 return true;
959 return false;
961 RefCountPtr< PDF_Object >
962 SimplePDF::PDF_Indirect::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
964 throw "PDF_Indirect::deepCopy must not be called. (However PDF_Indirect_in::deepCopy may be called.)";
966 /****************/
968 SimplePDF::PDF_Indirect_out::PDF_Indirect_out( RefCountPtr<PDF_Object> _obj, size_t _i, size_t _v )
969 : PDF_Indirect( _i, _v ), inUse( true ), obj( _obj )
971 SimplePDF::PDF_Indirect_out::~PDF_Indirect_out( )
973 void
974 SimplePDF::PDF_Indirect_out::writeTo( std::ostream & os, SimplePDF::PDF_xref * xref, const RefCountPtr< const PDF_Object > & self ) const
976 xref->enqueue( self.down_cast< const PDF_Indirect_out >( ) ); /* This shall not fail! */
977 os << xref->local( i ) << " " << v << " R" ; /* We must not call xref->local before xref->enqueue ! */
979 void
980 SimplePDF::PDF_Indirect_out::writeObject( std::ostream & os, SimplePDF::PDF_xref * xref ) const
982 if( inUse )
984 os << xref->local( i ) << " " << v << " obj" << endl ;
985 obj->writeTo( os, xref, obj );
986 os << endl << "endobj" << endl ;
990 /****************/
992 SimplePDF::PDF_Indirect_in::PDF_Indirect_in( size_t _i, size_t _v )
993 : PDF_Indirect( _i, _v ), PDFin( 0 )
995 SimplePDF::PDF_Indirect_in::~PDF_Indirect_in( )
997 RefCountPtr< PDF_Object >
998 SimplePDF::PDF_Indirect_in::deref( )
1000 if( PDFin == 0 )
1002 throw( "PDF_Indirect_in::deref: PDFin is not assigned" );
1004 return PDFin->readObjectNumbered( i, v );
1006 RefCountPtr< PDF_Object >
1007 SimplePDF::PDF_Indirect_in::deepCopy( RefCountPtr< PDF_Object > self, size_t * indirectObjectCounter, IndirectRemapType * remap )
1010 IndirectRemapType::iterator i( remap->find( *this ) );
1011 if( i != remap->end( ) )
1013 return i->second;
1016 return remap->insert( IndirectRemapType::value_type( *this, SimplePDF::indirect( ::deepCopy( deref( ), indirectObjectCounter, remap ),
1017 indirectObjectCounter ) ) ).first->second;
1020 /**************/
1022 SimplePDF::PDF_xref::PDF_xref( )
1023 : size_( 0 )
1025 /* The first position in the xref table is special. */
1026 localOrder_.push_back( 0 ); /* The first object shall appear in the xref table. */
1027 localNumbers_.push_back( 0 ); /* It has number 0. */
1028 byteOffsets_.push_back( 0 ); /* This is interpreted as "not in use" */
1029 generations_.push_back( 65535 );
1032 void
1033 SimplePDF::PDF_xref::enqueue( const RefCountPtr< const::PDF_Indirect_out > & obj )
1035 /* Grow big enough */
1036 while( byteOffsets_.size( ) <= obj->i )
1038 localNumbers_.push_back( 0 );
1039 byteOffsets_.push_back( 0 );
1040 generations_.push_back( 0 );
1043 if( byteOffsets_[ obj->i ] == 0 )
1045 indirectQueue_.push_back( obj );
1046 localNumbers_[ obj->i ] = localOrder_.size( );
1047 byteOffsets_[ obj->i ] = 1; /* We will change this later, this just indicates that the object has been put in queue. */
1048 localOrder_.push_back( obj->i );
1052 void
1053 SimplePDF::PDF_xref::writeRecursive( std::ostream & os )
1055 std::streamoff os_start;
1057 std::streamoff tmp = static_cast< streamoff >( os.tellp( ) );
1058 os.seekp( 0 );
1059 os_start = static_cast< streamoff >( os.tellp( ) ); /* Will this always be some kind of zero value? */
1060 os.seekp( tmp );
1062 while( ! indirectQueue_.empty( ) )
1064 RefCountPtr< const SimplePDF::PDF_Indirect_out > i_obj = indirectQueue_.front( );
1065 indirectQueue_.pop_front( );
1066 byteOffsets_[ i_obj->i ] = static_cast< streamoff >( os.tellp( ) ) - os_start;
1067 generations_[ i_obj->i ] = i_obj->v;
1068 i_obj->writeObject( os, this );
1072 size_t
1073 SimplePDF::PDF_xref::local( size_t i ) const
1075 return localNumbers_[ i ];
1078 void
1079 SimplePDF::PDF_xref::writeTable( std::ostream & os ) const
1081 if( size_ > 0 )
1083 throw "Internal error: PDF_xref::writeTable: This table has already been written.";
1085 size_ = localOrder_.size( );
1087 os << setfill( '0' ) ;
1088 os << "xref" << endl
1089 << 0 << " " << size_ << endl ;
1090 typedef typeof localOrder_ ListType;
1091 for( ListType::const_iterator i = localOrder_.begin( ); i != localOrder_.end( ); ++i )
1093 size_t o = byteOffsets_[ *i ];
1094 size_t v = generations_[ *i ];
1095 os << setw( 10 ) << o << ' ' << setw( 5 ) << v << ' ' << ( ( o == 0 ) ? 'f' : 'n' ) << ' ' << static_cast< char >( 10 ) ;
1099 size_t
1100 SimplePDF::PDF_xref::size( ) const
1102 if( size_ == 0 )
1104 throw "Internal error: PDF_xref::size: The size of the table is not determined yet. Call writeTable first.";
1106 return size_;
1110 /**************/
1112 RefCountPtr< PDF_Indirect_out >
1113 SimplePDF::indirect( RefCountPtr< PDF_Object > obj, size_t * i, size_t v )
1115 return RefCountPtr< PDF_Indirect_out >( new PDF_Indirect_out( obj, (*i)++, v ) );
1118 RefCountPtr< PDF_Object >
1119 SimplePDF::deepCopy( RefCountPtr< PDF_Object > obj, size_t * indirectObjectCounter, IndirectRemapType * remap )
1121 return obj->deepCopy( obj, indirectObjectCounter, remap );