/* Copyright (C) 1991 Aladdin Enterprises. All rights reserved.
Distributed by Free Software Foundation, Inc.
This file is part of Ghostscript.
Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the Ghostscript General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License. A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
/* Additional stream functions for filters */
/* Generic functions in sfilter.c */
extern int s_filter_flush(P1(stream
*));
extern int s_filter_close(P1(stream
*));
/* ------ ASCII85Encode ------ */
s_A85E_write_buf(register stream
*s
)
{ register stream
*strm
= s
->strm
;
register byte
*p
= s
->cbuf
;
register int count
= s
->cptr
+ 1 - p
;
((ulong
)(((uint
)p
[0] << 8) + p
[1]) << 16) +
(((uint
)p
[2] << 8) + p
[3]);
{ ulong q
= word
/ (85L*85*85*85);
word
-= q
* (85L*85*85*85);
w1
= (ushort
)(word
- q
* (85L*85));
sputc(strm
, w1
/ 85 + '!');
sputc(strm
, w1
% 85 + '!');
memcpy(s
->cbuf
, p
, count
);
s
->cptr
= s
->cbuf
+ count
- 1;
/* Close the stream, flushing a partial word. */
s_A85E_close(register stream
*s
)
{ stream
*strm
= s
->strm
;
(*s
->procs
.write_buf
)(s
);
count
= s
->cptr
- s
->cbuf
+ 1;
{ /* Handle leftover bytes. 1 <= count <= 3. */
/* All the bytes are at the beginning of the buffer. */
s
->cptr
[1] = s
->cptr
[2] = s
->cptr
[3] = 0xff;
swrite_string(&sst
, ebuf
, 5);
(*s
->procs
.write_buf
)(s
); /* force out final codes */
sputs(strm
, ebuf
, count
+ 1);
sputs(strm
, (byte
*)"~>", 2);
stream_procs s_A85E_procs
=
{ s_std_noavailable
, NULL
, s_filter_flush
, s_A85E_close
,
/* ------ ASCII85Decode ------ */
s_A85D_read_buf(register stream
*s
)
{ register stream
*strm
= s
->strm
;
register byte
*p
= s
->cbuf
;
byte
*limit
= p
+ s
->bsize
- 4;
if ( ccode
< 85 ) /* catches ch < '!' as well */
{ word
= word
* 85 + ccode
;
p
[1] = (byte
)(word
>> 16);
p
[2] = (byte
)((uint
)word
>> 8);
else if ( ch
== 'z' && ccount
== 0 )
p
[0] = p
[1] = p
[2] = p
[3] = 0,
else if ( scan_char_decoder
[ch
] == ctype_space
)
else if ( ch
== '~' && sgetc(strm
) == '>' )
case 1: /* syntax error */
word
= word
* (85L+85*85) + 0xffffffL
;
case 3: /* 2 odd bytes */
word
= word
* (85L*85) + 0xffffL
;
case 4: /* 3 odd bytes */
word
= word
* 85 + 0xffL
;
p
[2] = (byte
)(word
>> 8);
o2
: p
[1] = (byte
)(word
>> 16);
o1
: p
[0] = (byte
)(word
>> 24);
if ( !s
->end_status
) s
->end_status
= strm
->end_status
;
stream_procs s_A85D_procs
=
{ s_std_noavailable
, NULL
, s_std_null
, s_filter_close
,
/* ------ NullEncode ------ */
s_NullE_write_buf(register stream
*s
)
{ sputs(s
->strm
, s
->cbuf
, s
->cptr
- s
->cbuf
+ 1);
s_NullE_close(register stream
*s
)
return s_filter_close(s
);
stream_procs s_NullE_procs
=
{ s_std_noavailable
, NULL
, s_filter_flush
, s_NullE_close
,
/* ------ RunLengthEncode ------ */
s_RLE_init(register stream
*s
, uint rec_size
)
{ s
->record_size
= (rec_size
== 0 ? max_uint
: rec_size
);
s
->record_left
= s
->record_size
;
s_RLE_write_buf(register stream
*s
)
{ register stream
*strm
= s
->strm
;
register byte
*p
= s
->cbuf
;
uint count
= s
->cptr
- p
+ 1;
if ( count
> s
->record_left
)
if ( count
> 2 && p
[1] == p
[0] )
{ /* Recognize leading repeated byte */
while ( p
+ 1 < q
&& p
[1] == p
[0] );
sputc(strm
, 257 - (p
- beg
));
{ while ( p
+ 2 < q
&& (p
[1] != p
[0] || p
[2] != p
[0]) )
sputc(strm
, p
- beg
- 1);
sputs(strm
, beg
, p
- beg
);
s
->record_left
-= p
- beg
;
if ( s
->record_left
== 0 )
s
->record_left
= s
->record_size
;
s_RLE_close(register stream
*s
)
{ (*s
->procs
.write_buf
)(s
);
stream_procs s_RLE_procs
=
{ s_std_noavailable
, NULL
, s_filter_flush
, s_RLE_close
,
/* ------ RunLengthDecode ------ */
s_RLD_init(register stream
*s
)
s_RLD_read_buf(register stream
*s
)
{ register stream
*strm
= s
->strm
;
register byte
*p
= s
->cbuf
;
byte
*limit
= p
+ s
->bsize
;
if ( b
< 0 ) b
= sgetc(strm
);
if ( b
< 0 ) break; /* EOF/ERR */
{ if ( p
+ b
>= limit
) break; /* data won't fit */
count
= sgets(s
, p
, b
+ 1);
if ( strm
->end_status
) break; /* EOF/ERR */
else if ( b
== 128 ) /* end of data */
else if ( p
+ (257 - b
) > limit
)
if ( b
< 0 ) break; /* EOF/ERR */
if ( !s
->end_status
) s
->end_status
= strm
->end_status
;
stream_procs s_RLD_procs
=
{ s_std_noavailable
, NULL
, s_std_null
, s_std_close
,
/* ------ SubFileDecode ------ */
/* Currently equivalent to "NullDecode" */
s_SFD_read_buf(register stream
*s
)
{ stream
*strm
= s
->strm
;
uint count
= sgets(strm
, s
->cbuf
, s
->bsize
);
s
->endptr
= s
->cptr
+ count
;
s
->end_status
= strm
->end_status
;
stream_procs s_SFD_procs
=
{ s_std_noavailable
, NULL
, s_std_null
, s_filter_close
,