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
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
25 #include "pdfstructure.h"
26 #include "simplepdfo.h"
27 #include "simplepdfi.h"
29 #include "autoonoff.h"
33 using namespace SimplePDF
;
37 SimplePDF::PDF_Object::PDF_Object( )
40 SimplePDF::PDF_Object::~PDF_Object( )
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
)
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
>( );
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
>( );
110 template RefCountPtr
< SimplePDF::PDF_Vector
> down_cast_follow
< SimplePDF::PDF_Vector
>( RefCountPtr
< PDF_Object
> );
115 SimplePDF::PDF_Null::PDF_Null( )
117 SimplePDF::PDF_Null::~PDF_Null( )
121 SimplePDF::PDF_Null::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
128 SimplePDF::PDF_Boolean::PDF_Boolean( ValueType _value
)
131 SimplePDF::PDF_Boolean::~PDF_Boolean( )
134 SimplePDF::PDF_Boolean::ValueType
135 SimplePDF::PDF_Boolean::value( ) const
141 SimplePDF::PDF_Boolean::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
155 SimplePDF::PDF_Int::PDF_Int( PDF_Int::ValueType _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? */
163 my_value
= strtol( strvalue
, & end
, 10 );
166 throw "Internal error: Bad numeric int format";
169 SimplePDF::PDF_Int::~PDF_Int( )
173 SimplePDF::PDF_Int::value( ) const
179 SimplePDF::PDF_Int::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
186 SimplePDF::PDF_Float::PDF_Float( PDF_Float::ValueType _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? */
194 my_value
= strtod( strvalue
, & end
);
197 throw( "Internal error: Bad numeric float format" );
200 SimplePDF::PDF_Float::~PDF_Float( )
203 SimplePDF::PDF_Float::ValueType
PDF_Float::value( ) const
209 SimplePDF::PDF_Float::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
216 SimplePDF::PDF_String::PDF_String( )
218 SimplePDF::PDF_String::~PDF_String( )
223 SimplePDF::PDF_LiteralString::PDF_LiteralString( const string
& _str
)
226 SimplePDF::PDF_LiteralString::PDF_LiteralString( const char * _str
)
229 SimplePDF::PDF_LiteralString::PDF_LiteralString( const list
< RefCountPtr
< char > > & strs
)
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( ) );
245 my_str
= mem
.getPtr( );
247 SimplePDF::PDF_LiteralString::~PDF_LiteralString( )
251 SimplePDF::PDF_LiteralString::str( ) const
257 SimplePDF::PDF_LiteralString::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
260 for( const char * src
= my_str
.c_str( ); *src
!= '\0'; ++src
)
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( )
292 SimplePDF::PDF_HexString::hexstr( ) const
298 SimplePDF::PDF_HexString::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
300 os
<< "<" << my_hexstr
<< ">" ;
305 SimplePDF::PDF_Name::PDF_Name( const string
& _name
)
308 SimplePDF::PDF_Name::~PDF_Name( )
312 SimplePDF::PDF_Name::name( ) const
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
;
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( )
379 SimplePDF::PDF_Vector::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
382 for( VecType::const_iterator
i( vec
.begin( ) ); i
!= vec
.end( ); ++i
)
385 (*i
)->writeTo( os
, xref
, *i
);
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
)
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( ) ) ) ) );
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( ) ) ) ) );
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( ) ) ) ) );
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( ) ) ) ) );
448 SimplePDF::PDF_Dictionary::PDF_Dictionary( )
450 SimplePDF::PDF_Dictionary::PDF_Dictionary( const PDF_Dictionary
& orig
)
453 SimplePDF::PDF_Dictionary::~PDF_Dictionary( )
457 SimplePDF::PDF_Dictionary::writeTo( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, const RefCountPtr
< const PDF_Object
> & self
) const
460 for( DicType::const_iterator
i( dic
.begin( ) ); i
!= dic
.end( ); ++i
)
462 os
<< "/" << (i
->first
) << " " ;
463 (i
->second
)->writeTo( os
, xref
, i
->second
);
470 SimplePDF::PDF_Dictionary::writeToWithLength( std::ostream
& os
, SimplePDF::PDF_xref
* xref
, size_t len
) const
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
);
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( );
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( );
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( ) ) );
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( ) )
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
;
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
)
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( )
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.)";
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( );
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( )
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
;
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
);
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
;
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
;
696 class Auto_zlib_deflateEnd
700 Auto_zlib_deflateEnd( z_stream
* strm
)
703 ~Auto_zlib_deflateEnd( )
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. */
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: */
732 // Z_BEST_COMPRESSION
733 // Z_DEFAULT_COMPRESSION
735 /* allocate deflate state */
736 strm
.zalloc
= Z_NULL
;
738 strm
.opaque
= Z_NULL
;
739 ret
= deflateInit( & strm
, LEVEL
);
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
;
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
;
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." ) );
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( )
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 " ;
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
);
824 SimplePDF::PDF_Stream_in::writeDataDefilteredTo( std::ostream
& os
) const
826 if( dic
.find( "Filter" ) == dic
.end( ) )
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
>( ) )
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
] );
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
;
874 switch( inflateInit( & zs
) )
879 throw( "inflateInit failed" );
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
;
893 os
.write( outBuf
.getPtr( ), BUFSIZE
- zs
.avail_out
);
896 throw( "The inflate cycle did not finish with Z_STREAM_END" );
900 switch( inflateEnd( & zs
) )
905 throw( "inflateEnd failed" );
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 )
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
) );
934 SimplePDF::PDF_Indirect::PDF_Indirect( size_t _i
, size_t _v
)
937 SimplePDF::PDF_Indirect::~PDF_Indirect( )
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
)
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.)";
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( )
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 ! */
980 SimplePDF::PDF_Indirect_out::writeObject( std::ostream
& os
, SimplePDF::PDF_xref
* xref
) const
984 os
<< xref
->local( i
) << " " << v
<< " obj" << endl
;
985 obj
->writeTo( os
, xref
, obj
);
986 os
<< endl
<< "endobj" << endl
;
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( )
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( ) )
1016 return remap
->insert( IndirectRemapType::value_type( *this, SimplePDF::indirect( ::deepCopy( deref( ), indirectObjectCounter
, remap
),
1017 indirectObjectCounter
) ) ).first
->second
;
1022 SimplePDF::PDF_xref::PDF_xref( )
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 );
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
);
1053 SimplePDF::PDF_xref::writeRecursive( std::ostream
& os
)
1055 std::streamoff os_start
;
1057 std::streamoff tmp
= static_cast< streamoff
>( os
.tellp( ) );
1059 os_start
= static_cast< streamoff
>( os
.tellp( ) ); /* Will this always be some kind of zero value? */
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 );
1073 SimplePDF::PDF_xref::local( size_t i
) const
1075 return localNumbers_
[ i
];
1079 SimplePDF::PDF_xref::writeTable( std::ostream
& os
) const
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 ) ;
1100 SimplePDF::PDF_xref::size( ) const
1104 throw "Internal error: PDF_xref::size: The size of the table is not determined yet. Call writeTable first.";
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
);