[gs-commits] ghostpdl branch, pdfi, updated. jbig2dec-0.14-2466-g70d25d8
[email protected] (Ken Sharp) Mon, 18 Nov 2019 17:23:54 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, pdfi has been updated
via 70d25d8ffdd55c6c57e50541e68772b4bc341196 (commit)
from bb630cc20b3a1fe6a65266b0e42384d3fead94af (commit)
----------------------------------------------------------------------
commit 70d25d8ffdd55c6c57e50541e68772b4bc341196
Author: Ken Sharp <[email protected]>
Date: Mon Nov 18 17:23:03 2019 +0000
Merge master
diff --git a/Makefile.in b/Makefile.in
index a4317da..4f99d10 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -63,6 +63,14 @@ GPDLSRCDIR=@srcdir@/gpdl
GPDLGENDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
GPDLOBJDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
+URFSRCDIR=@srcdir@/urf
+URFGENDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
+URFOBJDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
+
+IMGSRCDIR=@srcdir@/gpdl/image
+IMGGENDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
+IMGOBJDIR=./$(BUILDDIRPREFIX)@OBJDIR_BSDMAKE_WORKAROUND@
+
CONTRIBDIR=@srcdir@/contrib
# Do not edit the next group of lines.
@@ -336,6 +344,12 @@ LCMS2_CFLAGS=-DSHARE_LCMS=$(SHARE_LCMS) @LCMS2_ENDIAN@ @SQRTF_SUBST@ @LCMS2_PTR
# Options are currently lcms or lcms2
WHICH_CMS=@WHICHLCMS@
+# Do we have URF support?
+ENABLE_URF=@ENABLEURF@
+GPDL_URF_TOP_OBJ=@GPDL_URF_TOP_OBJ@
+URF_INCLUDE=@URF_INCLUDE@
+URF_DEV=@URF_DEV@
+SURFX_H=@SURFX_H@
EXPATSRCDIR=@EXPATDIR@
EXPAT_CFLAGS=@EXPAT_CFLAGS@
@@ -570,7 +584,7 @@ FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev
$(GLD)seprlib.dev $(GLD)translib.dev $(GLD)cidlib.dev $(GLD)psf0lib.dev $(GLD)psf1lib.dev\
$(GLD)psf2lib.dev $(GLD)lzwd.dev $(GLD)sicclib.dev \
$(GLD)sjbig2.dev $(GLD)sjpx.dev $(GLD)ramfs.dev \
- $(GLD)pwgd.dev $(GLD)siscale.dev
+ $(GLD)pwgd.dev $(GLD)siscale.dev $(URF_DEV)
#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev
#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)ttfont.dev $(GLD)pipe.dev
diff --git a/Resource/Init/gs_cidfm.ps b/Resource/Init/gs_cidfm.ps
index 5eb25f0..cd9ed88 100644
--- a/Resource/Init/gs_cidfm.ps
+++ b/Resource/Init/gs_cidfm.ps
@@ -120,7 +120,12 @@ currentdict end def
(DroidSansFallback.ttf)
} if
} if
- concatstrings
+ % If CIDFSubstFont looks like a path/file (rather than just file)
+ % use it without the CIDFSubstPath string
+ dup .file_name_directory_separator rsearch
+ {pop pop pop exch pop}
+ {pop concatstrings}
+ ifelse
% The CSI data just has to be valid, the substition machinery will
% generally overwrite it with appropriate values for the missing font.
/CSI [(Identity) 0]
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
index 0fd4164..8c41aba 100644
--- a/Resource/Init/gs_lev2.ps
+++ b/Resource/Init/gs_lev2.ps
@@ -660,7 +660,7 @@ currentuserparams /WaitTimeout known
% Search for valid (iccprofiles) directory as a sibling to (Resource)
% and set it as a default if found.
LIBPATH {
- (Resource) search {
+ (Resource) rsearch {
exch pop exch pop (iccprofiles) concatstrings
.file_name_separator concatstrings
dup (default_gray.icc) concatstrings status {
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps
index 068514b..5559e6a 100644
--- a/Resource/Init/gs_res.ps
+++ b/Resource/Init/gs_res.ps
@@ -284,7 +284,7 @@ systemdict begin
dup .file_name_current eq {
pop
} {
- (Resource) search {
+ (Resource) rsearch {
exch concatstrings
exch pop
.file_name_separator concatstrings exit
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
index d4a3701..2f8b610 100644
--- a/Resource/Init/pdf_draw.ps
+++ b/Resource/Init/pdf_draw.ps
@@ -3104,7 +3104,10 @@ end
% Scaling due to -dPDFFitPage is not undone, to keep the correct border width
% compared to the size of the surrounding marks.
//systemdict /NoUserUnit .knownget not { //false } if not
- //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage
+ //systemdict /PDFFitPage known not and
+ % Don't apply USerUnit if we are passing it to the device
+ /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and
+ { % UserUnit is ignored if -dPDFFitPage
Page /UserUnit knownoget { div } if
} if
{} 2 index /S knownoget {
@@ -3148,7 +3151,10 @@ end
% Scaling due to -dPDFFitPage is not undone, to keep the correct border width
% compared to the size of the surrounding marks.
//systemdict /NoUserUnit .knownget not { //false } if not
- //systemdict /PDFFitPage known not and { % UserUnit is ignored if -dPDFFitPage
+ //systemdict /PDFFitPage known not and
+ % Don't apply USerUnit if we are passing it to the device
+ /PassUserUnit /GetDeviceParam .special_op {exch pop} {//false} ifelse not and
+ { % UserUnit is ignored if -dPDFFitPage
Page /UserUnit knownoget { div } if
} if
{} 2 index /S knownoget {
@@ -3631,6 +3637,7 @@ currentdict /set_bc_color undef
} ifelse
//endannottransparency exec
grestore
+ //false
}ifelse
} bind executeonly def
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
index 81b7af1..60deb64 100644
--- a/Resource/Init/pdf_font.ps
+++ b/Resource/Init/pdf_font.ps
@@ -857,176 +857,222 @@ setglobal
/.pdfdfndict mark
/defaultfontname /Helvetica
.dicttomark readonly def
+
+% This code attempts to use the FontName and FontDescriptor to find a
+% 'better' match for a missing font than the default font. There
+% are a list of fonts and mappings here (TTfonts) and in gs_font.ps
+% (.substitutefaces) which we can use to map from a requested font
+% family name to a substitute family. If that fails we check the
+% FontDescriptor Flags to attempt a (very slightly) better match.
+% We use Times-Roman for serif fonts and Helvetica for non-serif.
+% This all seems pretty poor to me, but its long-standing, so we
+% won't attempt to meddle with it.
+/pdfsubstitutefont {
+ % Stack: font-res fontname fontdesc
+
+ dup /Flags oget
+ dup 16#40 and -6 bitshift % 1, oblique/italic
+ 1 index 16#40000 and -17 bitshift add % 2, bold
+ exch 16#2 and 2 bitshift add % 8, serif
+
+ % We should look at the fixed flag, too.
+ % Stack: font-res fontname fontdesc properties
+
+ % Even though /FontName is a required key in FontDescriptor dict
+ % (As of the PDF 1.4 Reference Manual), In the case of missing
+ % /FontName key, we substitue /BaseFont for the value of /FontName.
+ % Yet another case of broken PDF's that Adobe Reader accepts.
+ 1 index dup /FontName known
+ {
+ /FontName oget
+ dup type /nametype ne
+ {
+ ( **** Error: /FontName in FontDescriptor is not a name.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ cvn
+ } if
+ }
+ {
+ ( **** Error: FontDescriptor missing required /FontName key. BaseFont name used.\n)
+ pdfformaterror
+ ( Output may be incorrect.\n) pdfformaterror
+ pop 2 index % grab the BaseFont from the stack.
+ } ifelse
+ .remove_font_name_prefix
+ exch
+
+ % Analyzes font name and extract "Bold" and "Narrow" properties
+ % which are not described by the FontDescriptor Flags.
+ % We also allow the font name analysis to override the Flags setting
+ % for Italic/Oblique as this gives us results more consistent with
+ % Acrobat.
+ 0 2 index //.fontnameproperties exec 7 and or
+
+ % Rebind the default font name to Helvetica so that
+ % fonts with no properties are handled correctly.
+ //.pdfdfndict begin .substitutefontname end
+
+ % Stack: font-res fontname fontdesc substname|null
+ Fontmap 1 index known
+ {//false}
+ { .buildnativefontmap pop NativeFontmap 1 index known not}
+ ifelse
+
+ {
+ % No available good substitution, use the standard one.
+ pop 1 index .substitutefont
+ } if
+
+ dup 3 index ne
+ {
+ QUIET not
+ {
+ (Substituting font ) print dup =only
+ ( for ) print 2 index =only (.) = flush
+ } if
+ % Send a warning to the device, in case its pdfwrite and we are in PDF/A mode
+ % In that case the substituted font may not (probably doesn't) have glyphs which
+ % match the /Widths of the original font, and that will cause a fault with PDF/A
+ % so we need to let the device know.
+ /SubstitutedFont /EventInfo .special_op
+ } if
+
+ pdffindcachedfont
+ % Stack: font-res fontname fontdesc font
+
+ % Some non-compliant files are missing FirstChar/LastChar,
+ % despite referencing a non-base14 font
+ 3 index /FirstChar knownoget
+ {
+ 0 % push an initial value for accumating the Widths
+ 0 string % and an empty string to interrogate the font
+ 7 index /Widths knownoget
+ {
+ 0 1 2 index length 1 sub
+ {
+ dup 2 index exch get
+ dup type /packedarraytype eq {exec} if % Handle entries which are indirect references (seriously ? !!)
+ dup 0 gt % We ignore entries of zero in the widths array
+ {
+ exch 5 index add % add FirstChar to the idx to get a char code
+ dup 64 gt 1 index 91 lt and % we only want to consider A~Z and....
+ 1 index 96 gt 2 index 123 lt and or % ... a~z
+ {
+ exch
+ 5 -1 roll add 4 1 roll % add the width to the accumulator on the stack
+ 1 string dup 0 4 -1 roll put
+ 3 -1 roll concatstrings exch % add the char code to the string
+ }
+ {
+ pop pop
+ } ifelse
+ }
+ {
+ pop pop
+ } ifelse
+ } for
+ pop % get rid of the Widths array
+ 3 -1 roll pop % get rid of the FirstChar value
+ dup length dup 0 gt
+ {
+ 3 -1 roll exch div % calculate an average width from the Widths array
+ gsave
+ 2 index 10 scalefont setfont
+ exch dup length exch stringwidth
+ grestore
+ pop 100 mul exch div div
+ % Only make the font smaller/narrower, not larger/wider
+ dup 1.0 lt
+ {
+ 0 0 2 index 0 0 6 array astore
+ exch //true .copyfontdict
+ dup /FontMatrix get 3 -1 roll matrix concatmatrix
+ exch dup 3 -1 roll /FontMatrix exch put
+ % we don't need to definfont here, we can leave that to .completefont below
+ }
+ {
+ pop
+ } ifelse
+ }
+ {
+ % no suitable Widths entries - carry on and hope for the best......
+ pop pop pop
+ } ifelse
+ }
+ {
+ % Broken file: no Widths array for non-base14 font - carry on and hope for the best......
+ ( **** Warning: Widths array missing in FontDescriptor for non-base14 font\n)
+ pdfformatwarning
+ pop pop pop
+ } ifelse
+ }
+ {
+ ( **** Warning: FirstChar value missing in FontDescriptor for non-base14 font\n)
+ pdfformatwarning
+ } ifelse
+ % Stack: font-res fontname fontdesc font
+
+ % If this is a small-caps font, replace the CharString
+ % entries for a..z.
+ exch /Flags oget 16#20000 and 0 ne
+ {
+ //true .copyfontdict
+ dup /CharStrings 2 copy get dup length dict .copydict
+ % stack: font-res fontname font font /CharStrings CharStringsdict
+ 5 index /FirstChar get 97 .max
+ 6 index /LastChar get 122 .min 1 exch
+ {
+
+ % Stack: font-res fontname font' font' /CharStrings charstrings code
+ % Note that this only remaps a-z, not accented characters.
+ 6 index /Widths oget 1 index 8 index /FirstChar get sub oget
+ 1 string dup 0 5 -1 roll put
+
+ % Stack: font-res font' font' /CharStrings charstrings code
+ % width (x)
+ 2 index exch dup cvn exch
+ dup 0 2 copy get 32 sub put 4 -1 roll
+ {
+ % Stack: operand (X) width
+ 0 setcharwidth exch pop
+ currentfont /FontMatrix get matrix invertmatrix concat
+ 0.7 dup scale 0 0 moveto show
+ } /exec cvx 4 packedarray cvx put
+ } for put
+ } if
+
+ dup /FontName get 2 index ne
+ {
+ //true .copyfontdict
+ 2 copy exch /FontName exch put
+ } if
+ exch pop .completefont
+} bind executeonly def
+
/pdffindfont { % <font-resource> <fontname> pdffindfont <font>
- % If the font isn't available, synthesize one based on
- % its descriptor.
- dup /Font resourcestatus {
+ % If the font isn't available, synthesize one based on
+ % its descriptor.
+ dup /Font resourcestatus
+ {
pop pop pdffindcachedfont
- } {
+ }
+ {
1 index /FontDescriptor knownoget {
- % Stack: font-res fontname fontdesc
- dup /Flags oget
- dup 16#40 and -6 bitshift % 1, oblique/italic
- 1 index 16#40000 and -17 bitshift add % 2, bold
- exch 16#2 and 2 bitshift add % 8, serif
- % We should look at the fixed flag, too.
- % Stack: font-res fontname fontdesc properties
-
- % Even though /FontName is a required key in FontDescriptor dict
- % (As of the PDF 1.4 Reference Manual), In the case of missing
- % /FontName key, we substitue /BaseFont for the value of /FontName.
- % Yet another case of broken PDF's that Adobe Reader accepts.
- 1 index dup /FontName known {
- /FontName oget
- dup type /nametype ne {
- ( **** Error: /FontName in FontDescriptor is not a name.\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- cvn
- } if
- } {
- ( **** Error: FontDescriptor missing required /FontName key. BaseFont name used.\n)
- pdfformaterror
- ( Output may be incorrect.\n) pdfformaterror
- pop 2 index % grab the BaseFont from the stack.
- } ifelse
- .remove_font_name_prefix
- exch
- % Analyzes font name and extract "Bold" and "Narrow" properties
- % which are not described by the FontDescriptor Flags.
- % We also allow the font name analysis to override the Flags setting
- % for Italic/Oblique as this gives us results more consistent with
- % Acrobat.
- 0 2 index //.fontnameproperties exec 7 and or
- % Rebind the default font name to Helvetica so that
- % fonts with no properties are handled correctly.
- //.pdfdfndict begin .substitutefontname end
- % Stack: font-res fontname fontdesc substname|null
- Fontmap 1 index known
- {//false}
- { .buildnativefontmap pop NativeFontmap 1 index known not} ifelse
-
+ /SUBSTFONT where not
{
- % No available good substitution, use the standard one.
- pop 1 index .substitutefont
- } if
- dup 3 index ne {
- QUIET not {
- (Substituting font ) print dup =only
- ( for ) print 2 index =only (.) = flush
- } if
- % Send a warning to the device, in case its pdfwrite and we are in PDF/A mode
- % In that case the substituted font may not (probably doesn't) have glyphs which
- % match the /Widths of the original font, and that will cause a fault with PDF/A
- % so we need to let the device know.
- /SubstitutedFont /EventInfo .special_op
- } if
- pdffindcachedfont
- % Stack: font-res fontname fontdesc font
-
- % Some non-compliant files are missing FirstChar/LastChar,
- % despite referencing a non-base14 font
- 3 index /FirstChar knownoget
- {
- 0 % push an initial value for accumating the Widths
- 0 string % and an empty string to interrogate the font
- 7 index /Widths knownoget
- {
- 0 1 2 index length 1 sub
- {
- dup 2 index exch get
- dup type /packedarraytype eq {exec} if % Handle entries which are indirect references (seriously ? !!)
- dup 0 gt % We ignore entries of zero in the widths array
- {
- exch 5 index add % add FirstChar to the idx to get a char code
- dup 64 gt 1 index 91 lt and % we only want to consider A~Z and....
- 1 index 96 gt 2 index 123 lt and or % ... a~z
- {
- exch
- 5 -1 roll add 4 1 roll % add the width to the accumulator on the stack
- 1 string dup 0 4 -1 roll put
- 3 -1 roll concatstrings exch % add the char code to the string
- }
- {
- pop pop
- } ifelse
- }
- {
- pop pop
- } ifelse
- } for
- pop % get rid of the Widths array
- 3 -1 roll pop % get rid of the FirstChar value
- dup length dup 0 gt
- {
- 3 -1 roll exch div % calculate an average width from the Widths array
-
- gsave
- 2 index 10 scalefont setfont
- exch dup length exch stringwidth
- grestore
- pop 100 mul exch div div
- % Only make the font smaller/narrower, not larger/wider
- dup 1.0 lt
- {
- 0 0 2 index 0 0 6 array astore
- exch //true .copyfontdict
- dup /FontMatrix get 3 -1 roll matrix concatmatrix
- exch dup 3 -1 roll /FontMatrix exch put
- % we don't need to definfont here, we can leave that to .completefont below
- }
- {
- pop
- } ifelse
- }
- {
- % no suitable Widths entries - carry on and hope for the best......
- pop pop pop
- } ifelse
- }
- {
- % Broken file: no Widths array for non-base14 font - carry on and hope for the best......
- ( **** Warning: Widths array missing in FontDescriptor for non-base14 font\n)
- pdfformatwarning
- pop pop pop
- } ifelse
+ pdfsubstitutefont
}
{
- ( **** Warning: FirstChar value missing in FontDescriptor for non-base14 font\n)
- pdfformatwarning
- } ifelse
- % Stack: font-res fontname fontdesc font
- % If this is a small-caps font, replace the CharString
- % entries for a..z.
-
- exch /Flags oget 16#20000 and 0 ne {
- //true .copyfontdict
- dup /CharStrings 2 copy get dup length dict .copydict
- % stack: font-res fontname font font /CharStrings CharStringsdict
- 5 index /FirstChar get 97 .max
- 6 index /LastChar get 122 .min 1 exch {
- % Stack: font-res fontname font' font' /CharStrings charstrings code
- % Note that this only remaps a-z, not accented characters.
- 6 index /Widths oget 1 index 8 index /FirstChar get sub oget
- 1 string dup 0 5 -1 roll put
- % Stack: font-res font' font' /CharStrings charstrings code
- % width (x)
- 2 index exch dup cvn exch
- dup 0 2 copy get 32 sub put 4 -1 roll {
- % Stack: operand (X) width
- 0 setcharwidth exch pop
- currentfont /FontMatrix get matrix invertmatrix concat
- 0.7 dup scale 0 0 moveto show
- } /exec cvx 4 packedarray cvx put
- } for put
- } if
- dup /FontName get 2 index ne {
- //true .copyfontdict
- 2 copy exch /FontName exch put
- } if
- exch pop .completefont
- } {
- % No descriptor available, use the default algorithm.
+ % User has defined SUBSTFONT, use the defined substitute font, do not
+ % try to be clever
+ pop % the dictionary containing SUBSTFONT
+ pop % the FontDescriptor
+ pdffindcachedfont
+ }ifelse
+ }
+ {
+ % No descriptor available, use the default algorithm.
pdffindcachedfont
} ifelse
} ifelse
@@ -2473,23 +2519,22 @@ currentdict /bndef undef
% if the font was defined in-line, we won't have a object number
dup /.gs.pdfobj# .knownget not { //null } if
} {
- dup /FontDescriptor knownoget {
% if the font was defined in-line, we won't have a object number
- dup /.gs.pdfobj# .knownget not { //null }if
- dup //null eq {
- exch pop
- }{
- exch dup /FontFile knownoget not {
- dup /FontFile2 knownoget not {
- dup /FontFile3 knownoget not {
- pop pop //null
- } {pop pop}ifelse
+ dup /.gs.pdfobj# .knownget not { //null }if
+ dup //null eq not {
+ 1 index /FontDescriptor knownoget {
+ dup /FontFile knownoget not {
+ dup /FontFile2 knownoget not {
+ dup /FontFile3 knownoget not {
+ pop pop //null
} {pop pop}ifelse
- }{pop pop}ifelse
- }ifelse
- }{
- //null
- } ifelse
+ } {pop pop}ifelse
+ }{pop pop}ifelse
+ }
+ {
+ pop //null
+ } ifelse
+ }if
} ifelse
3 1 roll
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
index 7c608c8..d771b1e 100644
--- a/Resource/Init/pdf_main.ps
+++ b/Resource/Init/pdf_main.ps
@@ -2505,9 +2505,26 @@ end readonly def
1
} {
1 index /UserUnit knownoget {
- PDFDEBUG { (Scaling due to UserUnit by ) print dup = flush } if
+ /PassUserUnit /GetDeviceParam .special_op {
+ exch pop dup {
+ [ /UserUnit 4 -1 roll .pdfputparams pop pop 1 exch
+ } if
+ }{
+ //false
+ }ifelse
+
+ not {
+ PDFDEBUG { (Scaling due to UserUnit by ) print dup = flush } if
+ } if
} {
- 1
+ /PassUserUnit /GetDeviceParam .special_op {
+ exch pop {
+ [ /UserUnit 1 .pdfputparams pop pop
+ } if
+ 1
+ }{
+ 1
+ } ifelse
} ifelse
} ifelse
} ifelse
@@ -2585,8 +2602,23 @@ currentdict /PDF2PS_matrix_key undef
% Set the page size.
//systemdict /NoUserUnit .knownget not { //false } if not {
3 index /UserUnit knownoget {
- dup 4 -1 roll mul 3 1 roll mul
- } if
+ /PassUserUnit /GetDeviceParam .special_op {
+ exch pop dup {
+ [ /UserUnit 4 -1 roll .pdfputparams pop pop
+ } if
+ }{
+ //false
+ }ifelse
+ not {
+ dup 4 -1 roll mul 3 1 roll mul
+ } if
+ } {
+ /PassUserUnit /GetDeviceParam .special_op {
+ exch pop {
+ [ /UserUnit 1 .pdfputparams pop pop
+ } if
+ }if
+ } ifelse
} if
} ifelse
2 array astore /PageSize exch def
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
index cc25751..28f2b35 100644
--- a/Resource/Init/pdf_ops.ps
+++ b/Resource/Init/pdf_ops.ps
@@ -1678,25 +1678,35 @@ end readonly def
% operations when the CTM is singular.
% Work around this here.
{
- matrix currentmatrix dup dup
- dup 0 get 0 eq 1 index 1 get 0 eq and {
- dup dup 2 get 0 eq { 0 }{ 1 } ifelse 1 put
- } if
- dup 2 get 0 eq 1 index 3 get 0 eq and {
- dup dup 1 get 0 eq { 3 }{ 2 } ifelse 1 put
- } if
- setmatrix
- currentpoint
- % don't worry about transparency for invisible text
- 4 index settextfillstate show % Tr was set to graphic state.
- moveto
- setmatrix
- % now set the currentpoint using the original matrix
- gsave
- setmatrix
- //false charpath currentpoint newpath
- grestore
- moveto
+ matrix currentmatrix
+ % Previously we tested specifically for a scale factor of 0,
+ % but bug #701875 has a CTM which is minute, but not zero. If
+ % we try to use that at anything except low resolution FreeType
+ % ends up trying to deal with glyph metrics where one dimension is 0
+ % and it throws an error. So instead of looking for zero, we'll look
+ % for a really tiny CTM.
+ % We also used to patch up the CTM, and still use it, but frankly
+ % this is too much trouble. If the CTM is tiny then the displacement
+ % due to drawing the text will also be tiny. Negligible in fact.
+ % So if its that small then lets just ignore it.
+ dup 0 get abs 0.00001 lt 1 index 1 get 0.00001 abs lt and not {
+ dup 2 get abs 0.00001 lt 1 index 3 get abs 0.00001 lt and not {
+ pop
+ currentpoint
+ % don't worry about transparency for invisible text
+ 2 index settextfillstate show % Tr was set to graphic state.
+ moveto
+ % now set the currentpoint using the original matrix
+ gsave
+ //false charpath currentpoint newpath
+ grestore
+ moveto
+ } {
+ pop pop
+ }ifelse
+ } {
+ pop pop
+ }ifelse
}
} {
{ //false charpath textrenderingprocs .currenttextrenderingmode get exec }
diff --git a/base/gdevdevn.c b/base/gdevdevn.c
index 00932ad..737f022 100644
--- a/base/gdevdevn.c
+++ b/base/gdevdevn.c
@@ -1395,7 +1395,9 @@ spotcmyk_print_page(gx_device_printer * pdev, gp_file * prn_stream)
/* Now create the output bit image files */
for (; lnum < bottom; ++lnum) {
- gdev_prn_get_bits(pdev, lnum, in, &data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &data);
+ if (code < 0)
+ goto prn_done;
/* Now put the pcm data into the output file */
if (npcmcolors) {
first_bit = bpc * (ncomp - npcmcolors);
diff --git a/base/gdevdflt.c b/base/gdevdflt.c
index 964f0aa..d493068 100644
--- a/base/gdevdflt.c
+++ b/base/gdevdflt.c
@@ -2123,7 +2123,8 @@ transform_pixel_region_render_skew(gx_device *dev, gx_default_transform_pixel_re
return (code < 0 ? code : 1);
/* Save position if error, in case we resume. */
err:
- buffer[0] = prev;
+ /* Only set buffer[0] if we've managed to set prev to something valid. */
+ if (prev != &initial_run[0]) buffer[0] = prev;
return code;
}
diff --git a/base/gdevvec.c b/base/gdevvec.c
index 351228b..7136d76 100644
--- a/base/gdevvec.c
+++ b/base/gdevvec.c
@@ -630,6 +630,11 @@ gdev_vector_dopath_init(gdev_vector_dopath_state_t *state,
gs_make_scaling(vdev->scale.x, vdev->scale.y, &state->scale_mat);
}
state->first = true;
+
+ /* This is purely to prevent Coverity from thinking gdev_vector_dopath()
+ could use uninitialised state->start.x. */
+ state->start.x = 0;
+ state->start.y = 0;
}
/*
diff --git a/base/gpmisc.c b/base/gpmisc.c
index 96052fc..fd4bc5e 100644
--- a/base/gpmisc.c
+++ b/base/gpmisc.c
@@ -743,7 +743,7 @@ gp_open_printer(const gs_memory_t *mem,
char fname[gp_file_name_sizeof],
int binary_mode)
{
- gp_file *file;
+ gp_file *file = NULL;
gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
gs_fs_list_t *fs = ctx->core->fs;
@@ -770,7 +770,7 @@ gp_open_scratch_file(const gs_memory_t *mem,
char *fname,
const char *mode)
{
- gp_file *file;
+ gp_file *file = NULL;
gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
gs_fs_list_t *fs = ctx->core->fs;
@@ -800,7 +800,7 @@ gp_open_scratch_file_rm(const gs_memory_t *mem,
char *fname,
const char *mode)
{
- gp_file *file;
+ gp_file *file = NULL;
gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
gs_fs_list_t *fs = ctx->core->fs;
diff --git a/base/gsicc_create.c b/base/gsicc_create.c
index d073257..ef46460 100644
--- a/base/gsicc_create.c
+++ b/base/gsicc_create.c
@@ -1206,7 +1206,7 @@ add_lutAtoBtype(unsigned char *input_ptr, gsicc_lutatob *lutatobparts)
}
/* Then the matrix */
if (lutatobparts->matrix != NULL) {
- add_matrixwithbias(curr_ptr,&(lutatobparts->matrix->cu.u),true);
+ add_matrixwithbias(curr_ptr,(float*) lutatobparts->matrix,true);
curr_ptr += (12*4);
/* M curves */
if (lutatobparts->m_curves != NULL) {
@@ -1537,7 +1537,7 @@ create_lutAtoBprofile(unsigned char **pp_buffer_in, icHeader *header,
/* Multiply the matrix in the AtoB object by the cam so that the data
is in D50 */
if (lutatobparts->matrix == NULL) {
- gsicc_create_copy_matrix3(cam, &(temp_matrix.cu.u));
+ gsicc_create_copy_matrix3(cam, (float*) &temp_matrix);
lutatobparts->matrix = &temp_matrix;
} else {
if (yonly) {
@@ -1759,7 +1759,7 @@ gsicc_create_abc_merge(gsicc_lutatob *atob_parts, gs_matrix3 *matrixLMN,
to the mapping of X=Y by the identity table. If there are b_curves
these have an output that is 16 bit. */
if (atob_parts->b_curves == NULL) {
- scale_matrix(&(atob_parts->matrix->cu.u), 2.0);
+ scale_matrix((float*) atob_parts->matrix, 2.0);
}
return 0;
}
diff --git a/base/gxclrast.c b/base/gxclrast.c
index 30c7e36..b75054f 100644
--- a/base/gxclrast.c
+++ b/base/gxclrast.c
@@ -608,6 +608,7 @@ in: /* Initialize for a new page. */
}
if (target != 0)
(*dev_proc(target, get_clipping_box))(target, &target_box);
+ memset(&gs_gstate, 0, sizeof(gs_gstate));
GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
code = gs_gstate_initialize(&gs_gstate, mem);
/* Remove the ICC link cache and replace with the device link cache
diff --git a/base/gxhintn.c b/base/gxhintn.c
index 1e3e429..dc28c00 100644
--- a/base/gxhintn.c
+++ b/base/gxhintn.c
@@ -467,8 +467,9 @@ static void t1_hinter__compute_rat_transform_coef(t1_hinter * self)
}
static inline void t1_hinter__adjust_matrix_precision(t1_hinter * self, fixed xx, fixed yy)
-{ fixed x = any_abs(xx), y = any_abs(yy);
- fixed c = (x > y ? x : y);
+{
+ ufixed x = any_abs(xx), y = any_abs(yy);
+ ufixed c = (x > y ? x : y);
while (c >= self->max_import_coord) {
/* Reduce the precision of ctmf to allow products to fit into 32 bits : */
diff --git a/base/gxiscale.c b/base/gxiscale.c
index 72e3257..3eec2f7 100644
--- a/base/gxiscale.c
+++ b/base/gxiscale.c
@@ -1204,6 +1204,7 @@ image_render_interpolate(gx_image_enum * penum, const byte * buffer,
int scaled_x_prev = 0;
gx_dda_fixed save_x_dda = pss->params.scale_dda.x;
+ devc.type = gx_dc_type_none; /* Needed for coverity, in call to color_is_pure() if color_handler is NULL. */
stream_w.limit = out + pss->params.WidthOut *
max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1;
stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut;
diff --git a/base/lib.mak b/base/lib.mak
index 2ffeb64..810af0a 100644
--- a/base/lib.mak
+++ b/base/lib.mak
@@ -595,6 +595,7 @@ spprint_h=$(GLSRC)spprint.h
spsdf_h=$(GLSRC)spsdf.h
srlx_h=$(GLSRC)srlx.h
spwgx_h=$(GLSRC)spwgx.h
+surfx_h=$(SURFX_H)
sstring_h=$(GLSRC)sstring.h
strimpl_h=$(GLSRC)strimpl.h
szlibx_h=$(GLSRC)szlibx.h
@@ -1942,6 +1943,16 @@ $(GLOBJ)spwgd.$(OBJ) : $(GLSRC)spwgd.c $(AK) $(stdio__h) $(memory__h)\
$(spwgx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS)
$(GLCC) $(GLO_)spwgd.$(OBJ) $(C_) $(GLSRC)spwgd.c
+# ---------------- URF RunLength decode filter ---------------- #
+
+urfd_=$(GLOBJ)surfd.$(OBJ)
+$(GLD)urfd.dev : $(LIB_MAK) $(ECHOGS_XE) $(urfd_) $(LIB_MAK) $(MAKEDIRS)
+ $(SETMOD) $(GLD)urfd $(urfd_)
+
+$(GLOBJ)surfd.$(OBJ) : $(URFSRCDIR)$(D)surfd.c $(AK) $(stdio__h) $(memory__h)\
+ $(surfx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS)
+ $(GLCC) $(GLO_)surfd.$(OBJ) $(C_) $(URFSRCDIR)$(D)surfd.c
+
# ---------------- String encoding/decoding filters ---------------- #
# These are used by the PostScript and PDF writers, and also by the
# PostScript interpreter.
diff --git a/base/spwgd.c b/base/spwgd.c
index 19ec764..cb04cb7 100644
--- a/base/spwgd.c
+++ b/base/spwgd.c
@@ -171,8 +171,17 @@ data_produced:
}
}
+static void
+s_PWGD_release(stream_state * st)
+{
+ stream_PWGD_state *const ss = (stream_PWGD_state *) st;
+
+ gs_free_object(st->memory, ss->line_buffer, "PWGD(close)");
+ ss->line_buffer = NULL;
+}
+
/* Stream template */
const stream_template s_PWGD_template = {
- &st_PWGD_state, s_PWGD_init, s_PWGD_process, 1, 1, NULL,
+ &st_PWGD_state, s_PWGD_init, s_PWGD_process, 1, 1, s_PWGD_release,
s_PWGD_set_defaults
};
diff --git a/base/unix-gcc.mak b/base/unix-gcc.mak
index c6445bb..8fea6eb 100644
--- a/base/unix-gcc.mak
+++ b/base/unix-gcc.mak
@@ -530,7 +530,7 @@ FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev
$(GLD)seprlib.dev $(GLD)translib.dev $(GLD)cidlib.dev $(GLD)psf0lib.dev $(GLD)psf1lib.dev\
$(GLD)psf2lib.dev $(GLD)lzwd.dev $(GLD)sicclib.dev \
$(GLD)sjbig2.dev $(GLD)sjpx.dev $(GLD)ramfs.dev \
- $(GLD)pwgd.dev
+ $(GLD)pwgd.dev $(GLD)urfd.dev
diff --git a/configure.ac b/configure.ac
index 201c363..de761cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -919,9 +919,6 @@ UFST_CFLAGS=
UFST_LIB_EXT=
FAPIUFST_MAK="\$(GLSRCDIR)\$(D)stub.mak"
-AC_ARG_ENABLE([fapi], AC_HELP_STRING([--disable-fapi],
- [Force use of the (deprecated) Artifex font scaler/renderer]))
-
if test x"$enable_fapi" != xno; then
dnl UFST detection
@@ -989,7 +986,7 @@ if test x"$enable_fapi" != xno; then
if test x"$FTSRCDIR" = x"src"; then
AC_MSG_RESULT([no])
- if test "x$PKGCONFIG" != x; then
+ if test x"$PKGCONFIG" != x""; then
AC_MSG_CHECKING(for system freetype2 >= 2.4.2 with pkg-config)
# pkg-config needs the libtool version, which != the freetype2 version <sigh!>
# There is a table of corresponding ft2<->libtool numbers in freetype/docs/VERSION.DLL
@@ -1001,7 +998,6 @@ if test x"$enable_fapi" != xno; then
SHARE_FT=1
else
AC_MSG_RESULT(no)
- AC_MSG_WARN([freetype library source not found...using native rasterizer])
AFS=1
fi
else
@@ -1035,6 +1031,10 @@ if test x"$enable_fapi" != xno; then
fi
fi
+if test x"$FT_BRIDGE" != x"1"; then
+ AC_MSG_ERROR([No usable Freetype source or library found])
+fi
+
AC_SUBST(INSERT_UFST_BRIDGE_EQUAL_ONE)
AC_SUBST(UFST_ROOT)
AC_SUBST(UFST_CFLAGS)
@@ -1849,6 +1849,33 @@ AC_SUBST(JPXDIR)
AC_SUBST(SHARE_JPX)
AC_SUBST(JPXDEVS)
+ENABLEURF=
+URF_DEVS=''
+URF_INCLUDE=
+URF_DEV=
+SURFX_H=
+AC_ARG_WITH([urf], AC_HELP_STRING([--without-urf],
+ [do not try to include URF support]))
+
+if test x$with_urf != xno; then
+ AC_MSG_CHECKING([for URF support])
+ if test -d $srcdir/urf; then
+ AC_MSG_RESULT([yes])
+ ENABLEURF="$(D_)URF_INCLUDED$(_D)"
+ URF_DEVS='urfgray urfrgb urfcmyk'
+ GPDL_URF_TOP_OBJ=$(GPDLOBJ)/$(GPDL_URF_TOP_OBJ_FILE)
+ URF_INCLUDE=$(I_)$(URFSRCDIR)$(_I)
+ URF_DEV=$(GLD)urfd.dev
+ SURFX_H=SURFX_H=$(URFSRCDIR)$(D)surfx.h
+fi
+fi
+
+AC_SUBST(ENABLEURF)
+AC_SUBST(GPDL_URF_TOP_OBJ)
+AC_SUBST(URF_INCLUDE)
+AC_SUBST(URF_DEV)
+AC_SUBST(SURFX_H)
+
AC_ARG_WITH([cal], AC_HELP_STRING([--without-cal],
[do not try to use the CAL library for acceleration]))
@@ -2191,6 +2218,7 @@ AC_ARG_ENABLE([compile-inits], AC_HELP_STRING([--disable-compile-inits],
AC_SUBST(COMPILE_INITS)
dnl look for drivers to compile...
+APPLE_DEVICES_REQUESTED="no"
AC_ARG_WITH(drivers,
[ --with-drivers=LIST Drivers to support, separated by commas.
Either list the drivers or use aliases:
@@ -2233,6 +2261,10 @@ if test "x$driversfile" != x; then
drivers="`tr '\n' ',' <$driversfile`"
fi
+if echo $drivers | grep 'APPLE\|iwhi\|iwlo\|iwlq' >/dev/null; then
+ APPLE_DEVICES_REQUESTED="yes"
+fi
+
dnl Check which drivers we'd like to support.
P_DEVS0=""
F_DEVS0=""
@@ -2251,6 +2283,7 @@ EPSON_DEVS='eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolo
CANON_DEVS='bj10e bj200 bjc600 bjc800 lbp8 lips3 bjcmono bjcgray bjccmyk bjccolor'
LEXMARK_DEVS='lxm5700m lxm3200 lex2050 lex3200 lex5700 lex7000'
BROTHER_DEVS='hl7x0 hl1240 hl1250'
+APPLE_DEVS='appledmp iwhi iwlo iwlq'
IBM_DEVS='ibmpro jetp3852'
OKI_DEVS='oki182 okiibm oki4w'
JAPAN_DEVS='lips4 lips4v ljet4pjl lj4dithp dj505j picty180 lips2p bjc880j pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 md50Mono md50Eco md1xMono escpage lp2000 npdl rpdl'
@@ -2293,7 +2326,7 @@ while test -n "$drivers"; do
fi
;;
PRINTERS)
- P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS"
+ P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS $URF_DEVS"
IJS_DEVS0="$IJSDEVS"
if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then
P_DEVS0="$P_DEVS0 $OPVP_DEVS"
@@ -2307,6 +2340,10 @@ while test -n "$drivers"; do
JBIG2_DEVS="$JBIG2FILEDEVS"
PNG_DEVS0="$PNGDEVS"
;;
+ APPLE)
+ # All Apple printers
+ P_DEVS0="$P_DEVS0 $APPLE_DEVS"
+ ;;
BMP)
# BMP file format
F_DEVS0="$F_DEVS0 $BMP_DEVS"
@@ -2498,6 +2535,14 @@ if test -n "$X11_DEVS0"; then
X11_DEVS=`(for i in $X11_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '`
fi
+# if the user explicitly requested the Apple devices, then hard fail if they aren't available
+if test x"$APPLE_DEVICES_REQUESTED" = x"yes" ; then
+ APDEVS=`echo $P_DEVS | grep 'APPLE\|iwhi\|iwlo\|iwlq'`
+ if test -z "$APDEVS" ; then
+ AC_MSG_ERROR([Requested Apple device(s) not available (iwhi, iwlo, and/or iwlq)])
+ fi
+fi
+
AC_SUBST(P_DEVS)
AC_SUBST(F_DEVS)
AC_SUBST(CUPS_DEVS)
diff --git a/contrib/contrib.mak b/contrib/contrib.mak
index ec02a73..bb26640 100644
--- a/contrib/contrib.mak
+++ b/contrib/contrib.mak
@@ -141,6 +141,30 @@ CONTRIBSRC=$(CONTRIBDIR)$(D)
###### ----------------------- End of catalog ----------------------- ######
+### --------------------- The Apple printer devices --------------------- ###
+### Note: these drivers were contributed by users. ###
+### ###
+### Maintained by Mike Galatean contact via https://bugs.ghostscript.com ###
+### ###
+
+appledmp_=$(DEVOBJ)gdevadmp.$(OBJ)
+
+$(DEVOBJ)gdevadmp.$(OBJ) : $(CONTRIBSRC)gdevadmp.c $(PDEVH) $(CONTRIB_MAK) $(MAKEDIRS)
+ $(DEVCC) $(DEVO_)gdevadmp.$(OBJ) $(C_) $(CONTRIBSRC)gdevadmp.c
+
+$(DD)appledmp.dev : $(appledmp_) $(DD)page.dev $(CONTRIB_MAK) $(MAKEDIRS)
+ $(SETPDEV) $(DD)appledmp $(appledmp_)
+
+$(DD)iwhi.dev : $(appledmp_) $(DD)page.dev $(CONTRIB_MAK) $(MAKEDIRS)
+ $(SETPDEV) $(DD)iwhi $(appledmp_)
+
+$(DD)iwlo.dev : $(appledmp_) $(DD)page.dev $(CONTRIB_MAK) $(MAKEDIRS)
+ $(SETPDEV) $(DD)iwlo $(appledmp_)
+
+$(DD)iwlq.dev : $(appledmp_) $(DD)page.dev $(CONTRIB_MAK) $(MAKEDIRS)
+ $(SETPDEV) $(DD)iwlq $(appledmp_)
+
+
### ----------------- The BJC-210/240/250/250ex/265/1000 ---------------- ###
###
diff --git a/contrib/gdevadmp.c b/contrib/gdevadmp.c
new file mode 100644
index 0000000..d48c0da
--- /dev/null
+++ b/contrib/gdevadmp.c
@@ -0,0 +1,410 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/*
+ * Apple DMP / Imagewriter driver
+ *
+ * This is a modification of Mark Wedel's Apple DMP and
+ * Jonathan Luckey's Imagewriter II driver to
+ * support the Imagewriter LQ's higher resolution (320x216):
+ * appledmp: 120dpi x 72dpi is still supported (yuck)
+ * iwlo: 160dpi x 72dpi
+ * iwhi: 160dpi x 144dpi
+ * iwlq: 320dpi x 216dpi
+ *
+ * This is also my first attempt to work with gs. I have not included the LQ's
+ * ability to print in colour. Perhaps at a later date I will tackle that.
+ *
+ * BTW, to get your Imagewriter LQ serial printer to work with a PC, attach it
+ * with a nullmodem serial cable.
+ *
+ * Scott Barker ([email protected])
+ */
+
+/*
+ * This is a modification of Mark Wedel's Apple DMP driver to
+ * support 2 higher resolutions:
+ * appledmp: 120dpi x 72dpi is still supported (yuck)
+ * iwlo: 160dpi x 72dpi
+ * iwhi: 160dpi x 144dpi
+ *
+ * The Imagewriter II is a bit odd. In pinfeed mode, it thinks its
+ * First line is 1 inch from the top of the page. If you set the top
+ * form so that it starts printing at the top of the page, and print
+ * to near the bottom, it thinks it has run onto the next page and
+ * the formfeed will skip a whole page. As a work around, I reverse
+ * the paper about a 1.5 inches at the end of the page before the
+ * formfeed to make it think its on the 'right' page. bah. hack!
+ *
+ * This is my first attempt to work with gs, so your milage may vary
+ *
+ * Jonathan Luckey ([email protected])
+ */
+
+/* This is a bare bones driver I developed for my apple Dot Matrix Printer.
+ * This code originally was from the epson driver, but I removed a lot
+ * of stuff that was not needed.
+ *
+ * The Dot Matrix Printer was a predecessor to the apple Imagewriter. Its
+ * main difference being that it was parallel.
+ *
+ * This code should work fine on Imagewriters, as they have a superset
+ * of commands compared to the DMP printer.
+ *
+ * This driver does not produce the smalles output files possible. To
+ * do that, it should look through the output strings and find repeat
+ * occurances of characters, and use the escape sequence that allows
+ * printing repeat sequences. However, as I see it, this the limiting
+ * factor in printing is not transmission speed to the printer itself,
+ * but rather, how fast the print head can move. This is assuming the
+ * printer is set up with a reasonable speed (9600 bps)
+ *
+ * WHAT THE CODE DOES AND DOES NOT DO:
+ *
+ * To print out images, it sets the printer for unidirection printing
+ * and 15 cpi (120 dpi). IT sets line feed to 1/9 of an inch (72 dpi).
+ * When finished, it sets things back to bidirection print, 1/8" line
+ * feeds, and 12 cpi. There does not appear to be a way to reset
+ * things to initial values.
+ *
+ * This code does not set for 8 bit characters (which is required). It
+ * also assumes that carriage return/newline is needed, and not just
+ * carriage return. These are all switch settings on the DMP, and
+ * I have configured them for 8 bit data and cr only.
+ *
+ * You can search for the strings Init and Reset to find the strings
+ * that set up the printer and clear things when finished, and change
+ * them to meet your needs.
+ *
+ * Also, you need to make sure that the printer daemon (assuming unix)
+ * doesn't change the data as it is being printed. I have set my
+ * printcap file (sunos 4.1.1) with the string:
+ * ms=pass8,-opost
+ * and it works fine.
+ *
+ * Feel free to improve this code if you want. However, please make
+ * sure that the old DMP will still be supported by any changes. This
+ * may mean making an imagewriter device, and just copying this file
+ * to something like gdevimage.c.
+ *
+ * The limiting factor of the DMP is the vertical resolution. However, I
+ * see no way to do anything about this. Horizontal resolution could
+ * be increased by using 17 cpi (136 dpi). I believe the Imagewriter
+ * supports 24 cpi (192 dpi). However, the higher dpi, the slower
+ * the printing.
+ *
+ * Dot Matrix Code by Mark Wedel ([email protected])
+ *
+ *
+ * As of Oct 2019, maintained by Mike Galatean (contact through https://bugs.ghostscript.com )
+ *
+ */
+
+#include "gdevprn.h"
+
+/* The device descriptors */
+static dev_proc_print_page(dmp_print_page);
+
+/* Standard DMP device */
+const gx_device_printer far_data gs_appledmp_device =
+prn_device(prn_bg_procs, "appledmp", /* The print_page proc is compatible with allowing bg printing */
+ 85, /* width_10ths, 8.5" */
+ 110, /* height_10ths, 11" */
+ 120, 72, /* X_DPI, Y_DPI */
+ 0, 0.5, 0.5, 0, /* margins */
+ 1, dmp_print_page);
+
+/* lowrez Imagewriter device */
+const gx_device_printer far_data gs_iwlo_device =
+prn_device(prn_bg_procs, "iwlo", /* The print_page proc is compatible with allowing bg printing */
+ 85, /* width_10ths, 8.5" */
+ 110, /* height_10ths, 11" */
+ 160, 72, /* X_DPI, Y_DPI */
+ 0, 0.5, 0.5, 0, /* margins */
+ 1, dmp_print_page);
+
+/* hirez Imagewriter device */
+const gx_device_printer far_data gs_iwhi_device =
+prn_device(prn_bg_procs, "iwhi", /* The print_page proc is compatible with allowing bg printing */
+ 85, /* width_10ths, 8.5" */
+ 110, /* height_10ths, 11" */
+ 160, 144, /* X_DPI, Y_DPI */
+ 0, 0.5, 0.5, 0, /* margins */
+ 1, dmp_print_page);
+
+/* LQ hirez Imagewriter device */
+const gx_device_printer far_data gs_iwlq_device =
+prn_device(prn_bg_procs, "iwlq", /* The print_page proc is compatible with allowing bg printing */
+ 85, /* width_10ths, 8.5" */
+ 110, /* height_10ths, 11" */
+ 320, 216,
+ 0, 0, 0.5, 0, /* margins */
+ 1, dmp_print_page);
+
+/* ------ Internal routines ------ */
+
+#define DMP 1
+#define IWLO 2
+#define IWHI 3
+#define IWLQ 4
+
+/* Send the page to the printer. */
+static int
+dmp_print_page(gx_device_printer *pdev, gp_file *gprn_stream)
+{
+ int dev_type;
+
+ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
+ /* Note that in_size is a multiple of 8. */
+ int in_size = line_size * 8;
+ /* FIXME: It would be better if this device used the gp_file and the gp_ API,
+ * rather than this "back door" approach
+ */
+ FILE *prn_stream = gp_get_file(gprn_stream);
+
+
+ byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "dmp_print_page(buf1)");
+ byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "dmp_print_page(buf2)");
+ byte *prn = (byte *)gs_malloc(pdev->memory, 3*in_size, 1, "dmp_print_page(prn)");
+
+ byte *in = buf1;
+ byte *out = buf2;
+ int lnum = 0;
+
+ /* Check allocations */
+ if ( buf1 == 0 || buf2 == 0 || prn == 0 )
+ {
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1,
+ "dmp_print_page(buf1)");
+ if ( buf2 )
+ gs_free(pdev->memory, (char *)buf2, in_size, 1,
+ "dmp_print_page(buf2)");
+ if ( prn )
+ gs_free(pdev->memory, (char *)prn, in_size, 1,
+ "dmp_print_page(prn)");
+ return_error(gs_error_VMerror);
+ }
+
+ if ( pdev->y_pixels_per_inch == 216 )
+ dev_type = IWLQ;
+ else if ( pdev->y_pixels_per_inch == 144 )
+ dev_type = IWHI;
+ else if ( pdev->x_pixels_per_inch == 160 )
+ dev_type = IWLO;
+ else
+ dev_type = DMP;
+
+ /* Initialize the printer and reset the margins. */
+
+ fputs("\r\n\033>\033T16", prn_stream);
+
+ switch(dev_type)
+ {
+ case IWLQ:
+ fputs("\033P\033a3", prn_stream);
+ break;
+ case IWHI:
+ case IWLO:
+ fputs("\033P", prn_stream);
+ break;
+ case DMP:
+ default:
+ fputs("\033q", prn_stream);
+ break;
+ }
+
+ /* Print lines of graphics */
+ while ( lnum < pdev->height )
+ {
+ byte *inp;
+ byte *in_end;
+ byte *out_end;
+ int lcnt,ltmp;
+ int count, passes;
+ byte *prn_blk, *prn_end, *prn_tmp;
+
+/* The apple DMP printer seems to be odd in that the bit order on
+ * each line is reverse what might be expected. Meaning, an
+ * underscore would be done as a series of 0x80, while on overscore
+ * would be done as a series of 0x01. So we get each
+ * scan line in reverse order.
+ */
+
+ switch (dev_type)
+ {
+ case IWLQ: passes = 3; break;
+ case IWHI: passes = 2; break;
+ case IWLO:
+ case DMP:
+ default: passes = 1; break;
+ }
+
+ for (count = 0; count < passes; count++)
+ {
+ for (lcnt=0; lcnt<8; lcnt++)
+ {
+ switch(dev_type)
+ {
+ case IWLQ: ltmp = lcnt + 8*count; break;
+ case IWHI: ltmp = 2*lcnt + count; break;
+ case IWLO:
+ case DMP:
+ default: ltmp = lcnt; break;
+ }
+
+ if ((lnum+ltmp)>pdev->height)
+ memset(in+lcnt*line_size,0,line_size);
+ else
+ gdev_prn_copy_scan_lines(pdev,
+ lnum+ltmp, in + line_size*(7 - lcnt),
+ line_size);
+ }
+
+ out_end = out;
+ inp = in;
+ in_end = inp + line_size;
+ for ( ; inp < in_end; inp++, out_end += 8 )
+ {
+ gdev_prn_transpose_8x8(inp, line_size,
+ out_end, 1);
+ }
+
+ out_end = out;
+
+ switch (dev_type)
+ {
+ case IWLQ: prn_end = prn + count; break;
+ case IWHI: prn_end = prn + in_size*count; break;
+ case IWLO:
+ case DMP:
+ default: prn_end = prn; break;
+ }
+
+ while ( (int)(out_end-out) < in_size)
+ {
+ *prn_end = *(out_end++);
+ if ((dev_type) == IWLQ) prn_end += 3;
+ else prn_end++;
+ }
+ }
+
+ switch (dev_type)
+ {
+ case IWLQ:
+ prn_blk = prn;
+ prn_end = prn_blk + in_size * 3;
+ while (prn_end > prn && prn_end[-1] == 0 &&
+ prn_end[-2] == 0 && prn_end[-3] == 0)
+ {
+ prn_end -= 3;
+ }
+ while (prn_blk < prn_end && prn_blk[0] == 0 &&
+ prn_blk[1] == 0 && prn_blk[2] == 0)
+ {
+ prn_blk += 3;
+ }
+ if (prn_end != prn_blk)
+ {
+ if ((prn_blk - prn) > 7)
+ fprintf(prn_stream,"\033U%04d%c%c%c",
+ (int)((prn_blk - prn)/3),
+ 0, 0, 0);
+ else
+ prn_blk = prn;
+ fprintf(prn_stream,"\033C%04d",
+ (int)((prn_end - prn_blk)/3));
+ fwrite(prn_blk, 1, (int)(prn_end - prn_blk),
+ prn_stream);
+ }
+ break;
+ case IWHI:
+ for (count = 0; count < 2; count++)
+ {
+ prn_blk = prn_tmp = prn + in_size*count;
+ prn_end = prn_blk + in_size;
+ while (prn_end > prn_blk && prn_end[-1] == 0)
+ prn_end--;
+ while (prn_blk < prn_end && prn_blk[0] == 0)
+ prn_blk++;
+ if (prn_end != prn_blk)
+ {
+ if ((prn_blk - prn_tmp) > 7)
+ fprintf(prn_stream,
+ "\033V%04d%c",
+ (int)(prn_blk-prn_tmp),
+ 0);
+ else
+ prn_blk = prn_tmp;
+ fprintf(prn_stream,"\033G%04d",
+ (int)(prn_end - prn_blk));
+ fwrite(prn_blk, 1,
+ (int)(prn_end - prn_blk),
+ prn_stream);
+ }
+ if (!count) fputs("\033T01\r\n",prn_stream);
+ }
+ fputs("\033T15",prn_stream);
+ break;
+ case IWLO:
+ case DMP:
+ default:
+ prn_blk = prn;
+ prn_end = prn_blk + in_size;
+ while (prn_end > prn_blk && prn_end[-1] == 0)
+ prn_end--;
+ while (prn_blk < prn_end && prn_blk[0] == 0)
+ prn_blk++;
+ if (prn_end != prn_blk)
+ {
+ if ((prn_blk - prn) > 7)
+ fprintf(prn_stream,"\033V%04d%c",
+ (int)(prn_blk - prn), 0);
+ else
+ prn_blk = prn;
+ fprintf(prn_stream,"\033G%04d",
+ (int)(prn_end - prn_blk));
+ fwrite(prn_blk, 1, (int)(prn_end - prn_blk),
+ prn_stream);
+ }
+ break;
+ }
+
+ fputs("\r\n",prn_stream);
+
+ switch (dev_type)
+ {
+ case IWLQ: lnum += 24 ; break;
+ case IWHI: lnum += 16 ; break;
+ case IWLO:
+ case DMP:
+ default: lnum += 8 ; break;
+ }
+ }
+
+ /* ImageWriter will skip a whole page if too close to end */
+ /* so skip back more than an inch */
+ if ( !(dev_type == DMP) )
+ fputs("\033T99\n\n\033r\n\n\n\n\033f", prn_stream);
+
+ /* Formfeed and Reset printer */
+ fputs("\033T16\f\033<\033B\033E", prn_stream);
+ fflush(prn_stream);
+
+ gs_free(pdev->memory, (char *)prn, in_size, 1, "dmp_print_page(prn)");
+ gs_free(pdev->memory, (char *)buf2, in_size, 1, "dmp_print_page(buf2)");
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "dmp_print_page(buf1)");
+ return 0;
+}
diff --git a/contrib/gdevdj9.c b/contrib/gdevdj9.c
index ef53373..af0ef5b 100644
--- a/contrib/gdevdj9.c
+++ b/contrib/gdevdj9.c
@@ -684,7 +684,7 @@ cdj970_put_params(gx_device * pdev, gs_param_list * plist)
return code;
if ((code = cdj_put_param_int(plist, "Duplex", &duplex, 0, 2, code)) < 0)
return code;
- if ((code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code)) < 0)
+ if ((code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1f, 9.0, code)) < 0)
return code;
if ((code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code)) < 0)
return code;
diff --git a/contrib/gdevlx32.c b/contrib/gdevlx32.c
index 0dd5d27..20b01fa 100644
--- a/contrib/gdevlx32.c
+++ b/contrib/gdevlx32.c
@@ -2220,7 +2220,7 @@ static int
fill_mono_buffer(pagedata *gendata, int vline)
{
byte *in_data, *data;
- int i, ret, ofs;
+ int i, ret, ofs, code = 0;
/* Initialize the "data" pointer, that will be used to
* scan all the lines in the buffer, and the "ofs" pointer
@@ -2242,8 +2242,10 @@ fill_mono_buffer(pagedata *gendata, int vline)
while(vline < gendata->numvlines)
{
/* Ask Ghostscript for one rasterized line */
- gdev_prn_get_bits((gx_device_printer *)gendata->dev,
+ code = gdev_prn_get_bits((gx_device_printer *)gendata->dev,
vline, data+ofs, &in_data);
+ if (code < 0)
+ return code;
/* And check if it's all zero: if not, break out of
* the loop. This nice trick with memcpy it's by Stephen
@@ -2301,8 +2303,10 @@ fill_mono_buffer(pagedata *gendata, int vline)
/* If we are not at the end of the page, copy one more
* scanline into the buffer.
*/
- gdev_prn_get_bits((gx_device_printer *)gendata->dev,
+ code = gdev_prn_get_bits((gx_device_printer *)gendata->dev,
vline, data+ofs, &in_data);
+ if (code < 0)
+ return code;
if(in_data != data+ofs)memcpy(data+ofs, in_data, gendata->numrbytes);
}
@@ -2333,7 +2337,7 @@ static int
init_buffer(pagedata *gendata)
{
byte *in_data, *data;
- int i, ret, p1, p2, ofs;
+ int i, ret, p1, p2, ofs, code = 0;
data = gendata->scanbuf;
ofs = gendata->goffset;
@@ -2375,8 +2379,11 @@ init_buffer(pagedata *gendata)
if(i < gendata->numvlines)
{
- gdev_prn_get_bits((gx_device_printer *)gendata->dev,
+ code = gdev_prn_get_bits((gx_device_printer *)gendata->dev,
i, data+ofs, &in_data);
+ if (code < 0)
+ return code;
+
if(in_data != data+ofs)memcpy(data+ofs, in_data, gendata->numrbytes);
}
diff --git a/contrib/gdevlx7.c b/contrib/gdevlx7.c
index 9f0f127..37f9697 100644
--- a/contrib/gdevlx7.c
+++ b/contrib/gdevlx7.c
@@ -581,6 +581,7 @@ lxmgen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
int lr_shift=((lxm_device*)pdev)->headSeparation;
byte *obp[LX7_BSW_H]; /* pointers to buffer lines */
int bufHeight;
+ int code = 0;
/* initiate vres mapping variable */
vres=LXR_600; /* default vertical resolution */
@@ -689,19 +690,24 @@ lxmgen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
int c1200; /* testing empty line for 1200dpi... */
/* copy one line & test for all zeroes */
- gdev_prn_get_bits(pdev, pheight-prest, /* current line No. */
+ code = gdev_prn_get_bits(pdev, pheight-prest, /* current line No. */
pbuf, /* our buffer if needed */
&ppbuf); /* returns pointer to scanline
* either our buffer or
* gs internal data buffer
*/
+ if (code < 0)
+ goto error;
+
if (vres==LXR_1200 && (pheight-prest+LXH_DSKIP1<pheight))
{
- gdev_prn_get_bits(pdev, pheight-prest+LXH_DSKIP1,
+ code = gdev_prn_get_bits(pdev, pheight-prest+LXH_DSKIP1,
/* current line No. */
pbuf+bwidth, /* our buffer if needed */
&ppbuf2);
c1200=LX_LINE_EMPTY(ppbuf2,bwidth);
+ if (code < 0)
+ goto error;
}
else
c1200=1;
@@ -791,13 +797,14 @@ lxmgen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* eject page */
lex_eject(prn_stream);
+error:
gs_free(pdev->memory->non_gc_memory, (char*)pbuf,rpbufsize, 1, "lxmgen_print_page(pbuf)");
gs_free(pdev->memory->non_gc_memory, (char*)outbuf,OUT_BUF_SIZE, 1, "lxmgen_print_page(outbuf)");
#ifdef DEBUG
dprintf1("[%s] print_page() end\n",pdev->dname);
#endif
- return 0;
+ return code;
}
static int
diff --git a/contrib/gdevmd2k.c b/contrib/gdevmd2k.c
index 374ca0e..afc82e9 100644
--- a/contrib/gdevmd2k.c
+++ b/contrib/gdevmd2k.c
@@ -486,7 +486,7 @@ alps_print_page(gx_device_printer *pdev, gp_file *prn_stream,
int c_comp, num_comp = pdev->color_info.num_components;
int n_comp = (dev_alps->mediaType == 1 ? 3 : num_comp);
int *error, *ep;
- int i, j;
+ int i, j, code = 0;
/* allocate memory */
work = (byte *)gs_malloc(pdev->memory->non_gc_memory, 3+sizeof(int), line_size,
@@ -528,7 +528,9 @@ alps_print_page(gx_device_printer *pdev, gp_file *prn_stream,
for(y = 0; y < y_height; y ++) {
uint len = line_size;
- gdev_prn_get_bits(pdev, y, in, &dp);
+ code = gdev_prn_get_bits(pdev, y, in, &dp);
+ if (code < 0)
+ return code;
switch (pdev->color_info.depth) {
case 4:
diff --git a/contrib/japanese/gdev10v.c b/contrib/japanese/gdev10v.c
index aa641de..f4c349d 100644
--- a/contrib/japanese/gdev10v.c
+++ b/contrib/japanese/gdev10v.c
@@ -219,7 +219,8 @@ bj10v_print_page(gx_device_printer *pdev, gp_file *prn_stream)
int x_skip_unit = bytes_per_column * (xres / 180);
int y_skip_unit = (yres / 180);
byte *in = (byte *)gs_malloc(pdev->memory->non_gc_memory, 8, line_size, "bj10v_print_page(in)");
- byte *out = (byte *)gs_malloc(pdev->memory->non_gc_memory, bits_per_column, line_size, "bj10v_print_page(out)");
+ /* We need one extra byte in <out> for our sentinel. */
+ byte *out = (byte *)gs_malloc(pdev->memory->non_gc_memory, bits_per_column * line_size + 1, 1, "bj10v_print_page(out)");
int lnum = 0;
int y_skip = 0;
int code = 0;
diff --git a/contrib/japanese/gdevlbp3.c b/contrib/japanese/gdevlbp3.c
index 096aecf..8cbc2ce 100644
--- a/contrib/japanese/gdevlbp3.c
+++ b/contrib/japanese/gdevlbp3.c
@@ -137,8 +137,8 @@ BoundImage(gx_device_printer *pDev, struct bounding *pBox)
height*10/Yres < 98 ? a5 :\
height*10/Yres < 109 ? b5 :\
height*10/Yres < 116 ? letter : a4;
- Xsize = Xres * mm_to_inch(PaperInfo[paper].w-100) / 160;
- Ysize = Yres * mm_to_inch(PaperInfo[paper].h-100) / 10;
+ Xsize = (int)(Xres * mm_to_inch(PaperInfo[paper].w-100) / 160);
+ Ysize = (int)(Yres * mm_to_inch(PaperInfo[paper].h-100) / 10);
/* ----==== Allocate momory ====---- */
if (LineSize < Xsize*2+1) {
LineSize = Xsize*2+1;
diff --git a/devices/devs.mak b/devices/devs.mak
index 0183de7..64aaa90 100644
--- a/devices/devs.mak
+++ b/devices/devs.mak
@@ -1947,6 +1947,25 @@ $(DEVOBJ)gdevpdfimg.$(OBJ) : $(DEVSRC)gdevpdfimg.c $(AK) $(gdevkrnlsclass_h) \
$(slzwx_h) $(szlibx_h) $(jpeglib__h) $(sdct_h) $(srlx_h) $(gsicc_cache_h) $(sjpeg_h)
$(DEVCC) $(DEVO_)gdevpdfimg.$(OBJ) $(C_) $(DEVSRC)gdevpdfimg.c
+### -------- URF device --------------------- ###
+urf=$(DEVOBJ)gdevurf.$(OBJ)
+$(DD)urfgray.dev : $(urf) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)urfgray $(urf)
+ $(ADDMOD) $(DD)urfgray -include $(GLD)page
+
+$(DD)urfrgb.dev : $(urf) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)urfrgb $(urf)
+ $(ADDMOD) $(DD)urfrgb -include $(GLD)page
+
+$(DD)urfcmyk.dev : $(urf) $(GLD)page.dev $(GDEV) $(DEVS_MAK) $(MAKEDIRS)
+ $(SETPDEV2) $(DD)urfcmyk $(urf)
+ $(ADDMOD) $(DD)urfcmyk -include $(GLD)page
+
+$(DEVOBJ)gdevurf.$(OBJ) : $(URFSRCDIR)$(D)gdevurf.c $(AK) $(PDEVH) \
+ $(gsparam_h) $(gdevdcrd_h) $(gscrd_h) $(gscrdp_h) $(gxlum_h) $(gxdcconv_h)\
+ $(gsutil_h) $(DEVS_MAK) $(MAKEDIRS)
+ $(DEVCC) $(DEVO_)gdevurf.$(OBJ) $(C_) $(URFSRCDIR)$(D)gdevurf.c
+
# Dependencies:
$(DEVSRC)gxfcopy.h:$(GLSRC)gsfont.h
$(DEVSRC)gxfcopy.h:$(GLSRC)gsmatrix.h
diff --git a/devices/gdev3852.c b/devices/gdev3852.c
index d984fa1..8438835 100644
--- a/devices/gdev3852.c
+++ b/devices/gdev3852.c
@@ -65,6 +65,7 @@ jetp3852_print_page(gx_device_printer *pdev, gp_file *prn_stream)
unsigned int count,tempcnt;
unsigned char vtp,cntc1,cntc2;
int line_size_color_plane;
+ int code = 0;
byte data[DATA_SIZE];
byte plane_data[LINE_SIZE * 3];
@@ -90,8 +91,10 @@ jetp3852_print_page(gx_device_printer *pdev, gp_file *prn_stream)
for ( lnum = 0; lnum < pdev->height; lnum++ ) {
byte *end_data = data + line_size;
- gdev_prn_copy_scan_lines(pdev, lnum,
+ code = gdev_prn_copy_scan_lines(pdev, lnum,
(byte *)data, line_size);
+ if (code < 0)
+ break;
/* Remove trailing 0s. */
while ( end_data > data && end_data[-1] == 0 )
end_data--;
@@ -173,5 +176,5 @@ jetp3852_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* eject page */
gp_fputs("\014", prn_stream);
- return 0;
+ return code;;
}
diff --git a/devices/gdev4081.c b/devices/gdev4081.c
index fe40b2c..bd5c52d 100644
--- a/devices/gdev4081.c
+++ b/devices/gdev4081.c
@@ -38,21 +38,19 @@ r4081_print_page(gx_device_printer *pdev, gp_file *prn_stream)
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
int out_size = ((pdev->width + 7) & -8) ;
byte *out = (byte *)gs_malloc(pdev->memory, out_size, 1, "r4081_print_page(out)");
- int lnum = 0;
+ int lnum = 0, code = 0;
int last = pdev->height;
/* Check allocations */
if ( out == 0 )
- { if ( out )
- gs_free(pdev->memory, (char *)out, out_size, 1,
- "r4081_print_page(out)");
- return -1;
- }
+ return_error(gs_error_VMerror);
/* find the first line which has something to print */
while ( lnum < last )
{
- gdev_prn_copy_scan_lines(pdev, lnum, (byte *)out, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *)out, line_size);
+ if (code < 0)
+ goto xit;
if ( out[0] != 0 ||
memcmp((char *)out, (char *)out+1, line_size-1)
)
@@ -62,7 +60,9 @@ r4081_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* find the last line which has something to print */
while (last > lnum) {
- gdev_prn_copy_scan_lines(pdev, last-1, (byte *)out, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, last-1, (byte *)out, line_size);
+ if (code < 0)
+ goto xit;
if ( out[0] != 0 ||
memcmp((char *)out, (char *)out+1, line_size-1)
)
@@ -77,7 +77,9 @@ r4081_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* Print lines of graphics */
while ( lnum < last )
{
- gdev_prn_copy_scan_lines(pdev, lnum, (byte *)out, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *)out, line_size);
+ if (code < 0)
+ goto xit;
gp_fwrite(out, sizeof(char), line_size, prn_stream);
lnum ++;
}
@@ -85,6 +87,7 @@ r4081_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* Eject the page and reinitialize the printer */
gp_fputs("\f\033\rP", prn_stream);
+xit:
gs_free(pdev->memory, (char *)out, out_size, 1, "r4081_print_page(out)");
- return 0;
+ return code;
}
diff --git a/devices/gdev4693.c b/devices/gdev4693.c
index 7e18054..baa975c 100644
--- a/devices/gdev4693.c
+++ b/devices/gdev4693.c
@@ -83,7 +83,7 @@ t4693d_print_page(gx_device_printer *dev, gp_file *ps_stream)
char *p;
ushort data_size = line_size/prn_dev->width;
int checksum;
- int lnum;
+ int lnum, code = 0;
int i;
#if !ARCH_IS_BIG_ENDIAN
byte swap;
@@ -121,12 +121,14 @@ t4693d_print_page(gx_device_printer *dev, gp_file *ps_stream)
/* write header */
if (gp_fwrite(header,1,22,ps_stream) != 22) {
errprintf(dev->memory, "Could not write header (t4693d).\n");
- gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return_error(gs_error_ioerror);
+ code = gs_note_error(gs_error_ioerror);
+ goto xit;
}
for (lnum = 0; lnum < prn_dev->height; lnum++) {
- gdev_prn_copy_scan_lines(prn_dev,lnum,data,line_size);
+ code = gdev_prn_copy_scan_lines(prn_dev,lnum,data,line_size);
+ if (code < 0)
+ goto xit;
for (i = 0; i < line_size; i += data_size) {
@@ -147,32 +149,33 @@ t4693d_print_page(gx_device_printer *dev, gp_file *ps_stream)
break;
default:
errprintf(dev->memory,"Bad depth (%d) t4693d.\n",depth);
- gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return_error(gs_error_rangecheck);
+ code = gs_note_error(gs_error_rangecheck);
+ goto xit;
}
if (gp_fwrite(&data[i],1,data_size,ps_stream) != data_size) {
errprintf(dev->memory,"Could not write pixel (t4693d).\n");
- gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return_error(gs_error_ioerror);
+ code = gs_note_error(gs_error_ioerror);
+ goto xit;
}
}
if (gp_fputc(0x02,ps_stream) != 0x02) {
errprintf(dev->memory,"Could not write EOL (t4693d).\n");
- gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return_error(gs_error_ioerror);
+ code = gs_note_error(gs_error_ioerror);
+ goto xit;
}
}
if (gp_fputc(0x01,ps_stream) != 0x01) {
errprintf(dev->memory,"Could not write EOT (t4693d).\n");
- gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return_error(gs_error_ioerror);
+ code = gs_note_error(gs_error_ioerror);
+ /* fall through to xit: */
}
+xit:
gs_free(dev->memory, data, line_size, 1, "t4693d_print_page");
- return(0);
+ return(code);
}
diff --git a/devices/gdev8510.c b/devices/gdev8510.c
index 7d235b5..17938f7 100644
--- a/devices/gdev8510.c
+++ b/devices/gdev8510.c
@@ -68,9 +68,13 @@ m8510_print_page(gx_device_printer *pdev, gp_file *prn_stream)
while ( lnum < pdev->height ) {
/* get a raster */
for (i = 7; i >= 0; i--) {
- gdev_prn_copy_scan_lines(pdev, lnum, &in1[i*line_size], line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, &in1[i*line_size], line_size);
+ if (code < 0)
+ goto out;
lnum++;
- gdev_prn_copy_scan_lines(pdev, lnum, &in2[i*line_size], line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, &in2[i*line_size], line_size);
+ if (code < 0)
+ goto out;
lnum++;
}
diff --git a/devices/gdevatx.c b/devices/gdevatx.c
index fd68386..08c8ba5 100644
--- a/devices/gdevatx.c
+++ b/devices/gdevatx.c
@@ -202,7 +202,9 @@ atx_print_page(gx_device_printer *pdev, gp_file *f, int max_width_bytes)
byte *end;
int count;
- gdev_prn_get_bits(pdev, lnum, buf, &row);
+ code = gdev_prn_get_bits(pdev, lnum, buf, &row);
+ if (code < 0)
+ goto done;
/* Clear any trailing padding bits */
row[endidx] &= mask;
/* Find the end of the non-blank data. */
diff --git a/devices/gdevbit.c b/devices/gdevbit.c
index 98ef8d4..d0c7711 100644
--- a/devices/gdevbit.c
+++ b/devices/gdevbit.c
@@ -792,19 +792,22 @@ bit_print_page(gx_device_printer * pdev, gp_file * prn_stream)
int bottom = ((gx_device_bit *)pdev)->LastLine >= pdev->height ? pdev->height - 1 :
((gx_device_bit *)pdev)->LastLine;
int line_count = any_abs(bottom - lnum);
- int i, step = lnum > bottom ? -1 : 1;
+ int code = 0, i, step = lnum > bottom ? -1 : 1;
if (in == 0)
return_error(gs_error_VMerror);
if ((lnum == 0) && (bottom == 0))
line_count = pdev->height - 1; /* default when LastLine == 0, FirstLine == 0 */
for (i = 0; i <= line_count; i++, lnum += step) {
- gdev_prn_get_bits(pdev, lnum, in, &data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &data);
+ if (code < 0)
+ goto done;
if (!nul)
gp_fwrite(data, 1, line_size, prn_stream);
}
+done:
gs_free_object(pdev->memory, in, "bit_print_page(in)");
- return 0;
+ return code;
}
/* For tags device go ahead and add in the size so that we can strip and create
@@ -835,10 +838,11 @@ bittags_print_page(gx_device_printer * pdev, gp_file * prn_stream)
line_count = pdev->height - 1; /* default when LastLine == 0, FirstLine == 0 */
for (i = 0; i <= line_count; i++, lnum += step) {
if ((code = gdev_prn_get_bits(pdev, lnum, in, &data)) < 0)
- return code;
+ goto done;
if (!nul)
gp_fwrite(data, 1, line_size, prn_stream);
}
+done:
gs_free_object(pdev->memory, in, "bit_print_page(in)");
return 0;
}
diff --git a/devices/gdevbj10.c b/devices/gdevbj10.c
index 00f8569..3423ebc 100644
--- a/devices/gdevbj10.c
+++ b/devices/gdevbj10.c
@@ -312,7 +312,8 @@ bj10e_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* Copy 1 scan line and test for all zero. */
code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
- if ( code < 0 ) goto xit;
+ if ( code < 0 )
+ goto fin;
/* The mem... or str... functions should be faster than */
/* the following code, but all systems seem to implement */
/* them so badly that this code is faster. */
diff --git a/devices/gdevbmp.c b/devices/gdevbmp.c
index 3c6630e..f8ce596 100644
--- a/devices/gdevbmp.c
+++ b/devices/gdevbmp.c
@@ -162,7 +162,9 @@ bmp_print_page(gx_device_printer * pdev, gp_file * file)
/* BMP files want the image in bottom-to-top order! */
for (y = pdev->height - 1; y >= 0; y--) {
- gdev_prn_copy_scan_lines(pdev, y, row, raster);
+ code = gdev_prn_copy_scan_lines(pdev, y, row, raster);
+ if (code < 0)
+ goto done;
gp_fwrite((const char *)row, bmp_raster, 1, file);
}
diff --git a/devices/gdevccr.c b/devices/gdevccr.c
index 9fb22f3..2080d78 100644
--- a/devices/gdevccr.c
+++ b/devices/gdevccr.c
@@ -145,6 +145,7 @@ ccr_print_page(gx_device_printer *pdev, gp_file *pstream)
int cmy, c, m, y;
byte *in;
byte *data;
+ int code = 0;
if((in = (byte *)gs_malloc(pdev->memory, line_size, 1, "gsline")) == NULL)
return_error(gs_error_VMerror);
@@ -156,7 +157,9 @@ ccr_print_page(gx_device_printer *pdev, gp_file *pstream)
}
for ( l = 0; l < lnum; l++ )
- { gdev_prn_get_bits(pdev, l, in, &data);
+ { code = gdev_prn_get_bits(pdev, l, in, &data);
+ if (code < 0)
+ goto xit;
if(alloc_line(pdev->memory, &linebuf[l], pixnum))
{
gs_free(pdev->memory, in, line_size, 1, "gsline");
@@ -191,9 +194,10 @@ write_cpass(linebuf, lnum, CPASS, pstream);
CCFILEEND(pstream);
/* clean up */
+xit:
gs_free(pdev->memory, in, line_size, 1, "gsline");
free_rb_line( pdev->memory, linebuf, lnum, pixnum );
-return 0;
+return code;
}
/* ------ Internal routines ------ */
diff --git a/devices/gdevcdj.c b/devices/gdevcdj.c
index bfe60b5..50a1d62 100644
--- a/devices/gdevcdj.c
+++ b/devices/gdevcdj.c
@@ -2022,6 +2022,7 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype)
int compression = 0;
int scan = 0;
int *errors[2];
+ int code = 0;
const char *cid_string = (const char*) 0;
byte *data[4], *plane_data[4][4], *out_data;
byte *out_row, *out_row_alt;
@@ -2414,7 +2415,9 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype)
word *data_words = (word *)data[scan];
register word *end_data = data_words + line_size_words;
- gdev_prn_copy_scan_lines(pdev, lnum, data[scan], line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, data[scan], line_size);
+ if (code < 0)
+ goto xit;
/* Mask off 1-bits beyond the line width. */
end_data[-1] &= rmask;
@@ -2744,11 +2747,12 @@ hp_colour_print_page(gx_device_printer * pdev, gp_file * prn_stream, int ptype)
} else
gp_fputs("\033&l0H", prn_stream);
+xit:
/* free temporary storage */
gs_free(pdev->memory, (char *) eg.storage, eg.storage_size_words, W, "ep_print_buffer");
gs_free(pdev->memory, (char *) storage, storage_size_words, W, "hp_colour_print_page");
- return 0;
+ return code;
}
/*
diff --git a/devices/gdevcfax.c b/devices/gdevcfax.c
index d6fbebc..6f6419a 100644
--- a/devices/gdevcfax.c
+++ b/devices/gdevcfax.c
@@ -149,7 +149,9 @@ cfax_stream_print_page_width(gx_device_printer * pdev, gp_file * prn_stream,
if (code < 0)
return_error(gs_error_limitcheck);
/* Now, get the bits and encode them */
- gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if (code < 0)
+ goto done;
if (col_size > in_size) {
memset(in + in_size , 0, col_size - in_size);
}
diff --git a/devices/gdevcif.c b/devices/gdevcif.c
index 217e43d..66f61ce 100644
--- a/devices/gdevcif.c
+++ b/devices/gdevcif.c
@@ -46,10 +46,12 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
{ int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
int lnum;
byte *in = (byte *)gs_malloc(pdev->memory, line_size, 1, "cif_print_page(in)");
- char *s, *fname;
+ char *s;
+ const char *fname;
int scanline, scanbyte;
int length, start; /* length is the number of successive 1 bits, */
/* start is the set of 1 bit start position */
+ int code = 0;
if (in == 0)
return_error(gs_error_VMerror);
@@ -57,7 +59,7 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
#ifdef CLUSTER
fname = "clusterout";
#else
- fname = pdev->fname;
+ fname = (const char *)(pdev->fname);
#endif
if ((s = strchr(fname, '.')) == NULL)
length = strlen(fname) + 1;
@@ -72,7 +74,9 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
gs_free(pdev->memory, s, length+1, 1, "cif_print_page(s)");
for (lnum = 0; lnum < pdev->height; lnum++) {
- gdev_prn_copy_scan_lines(pdev, lnum, in, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, in, line_size);
+ if (code < 0)
+ goto xit;
length = 0;
for (scanline = 0; scanline < line_size; scanline++)
#ifdef TILE /* original, simple, inefficient algorithm */
@@ -98,6 +102,7 @@ cif_print_page(gx_device_printer *pdev, gp_file *prn_stream)
#endif
}
gp_fprintf(prn_stream, "DF;\nC1;\nE\n");
+xit:
gs_free(pdev->memory, in, line_size, 1, "cif_print_page(in)");
- return 0;
+ return code;
}
diff --git a/devices/gdevclj.c b/devices/gdevclj.c
index 0081ed4..542bb8e 100644
--- a/devices/gdevclj.c
+++ b/devices/gdevclj.c
@@ -428,6 +428,7 @@ clj_print_page(
double fs_res = pdev->HWResolution[0] / 72.0;
double ss_res = pdev->HWResolution[1] / 72.0;
int imageable_width, imageable_height;
+ int code = 0;
/* no paper size at this point is a serious error */
if (psize == 0)
@@ -479,7 +480,9 @@ clj_print_page(
for (i = 0; i < imageable_height; i++) {
int clen[3];
- gdev_prn_copy_scan_lines(pdev, i, data, lsize);
+ code = gdev_prn_copy_scan_lines(pdev, i, data, lsize);
+ if (code < 0)
+ goto xit;
/* The 'lsize' bytes of data have the blank margin area at the end due */
/* to the 'initial_matrix' offsets that are applied. */
@@ -503,11 +506,12 @@ clj_print_page(
/* PCL will take care of blank lines at the end */
gp_fputs("\033*rC\f", prn_stream);
+xit:
/* free the buffers used */
gs_free_object(mem, cdata[0], "clj_print_page(cdata)");
gs_free_object(mem, data, "clj_print_page(data)");
- return 0;
+ return code;
}
/* CLJ device methods */
diff --git a/devices/gdevcljc.c b/devices/gdevcljc.c
index 703f263..6593326 100644
--- a/devices/gdevcljc.c
+++ b/devices/gdevcljc.c
@@ -68,7 +68,7 @@ cljc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
code = gdev_prn_copy_scan_lines(pdev, i, (byte *) data, raster);
if (code < 0)
- break;
+ goto out;
compressed_size = gdev_pcl_mode3compress(raster, data, prow, cdata);
gp_fprintf(prn_stream, "\033*b%dW", compressed_size);
gp_fwrite(cdata, sizeof(byte), compressed_size, prn_stream);
diff --git a/devices/gdevdjtc.c b/devices/gdevdjtc.c
index fa4681a..5fb1a4b 100644
--- a/devices/gdevdjtc.c
+++ b/devices/gdevdjtc.c
@@ -75,6 +75,7 @@ djet500c_print_page(gx_device_printer *pdev, gp_file *fprn)
byte *plane3=NULL;
int bitSize=0;
int planeSize=0;
+ int code = 0;
/* select the most compressed mode available & clear tmp storage */
/* put printer in known state */
@@ -122,7 +123,9 @@ djet500c_print_page(gx_device_printer *pdev, gp_file *fprn)
{
byte *endData;
- gdev_prn_copy_scan_lines(pdev, lnum, bitData, lineSize);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, bitData, lineSize);
+ if (code < 0)
+ goto xit;
/* Identify and skip blank lines */
endData = bitData + lineSize;
@@ -149,6 +152,10 @@ djet500c_print_page(gx_device_printer *pdev, gp_file *fprn)
plane1=(byte*)malloc(planeSize+8);
plane2=(byte*)malloc(planeSize+8);
plane3=(byte*)malloc(planeSize+8);
+ if (plane1 == NULL || plane2 == NULL || plane3 == NULL) {
+ code = gs_error_VMerror;
+ goto xit;
+ }
}
/* Transpose the data to get pixel planes. */
for (k=i=0; k<lineLen; i+=8, k++)
@@ -207,13 +214,14 @@ djet500c_print_page(gx_device_printer *pdev, gp_file *fprn)
/* eject page */
gp_fputs("\033&l0H", fprn);
+xit:
/* release allocated memory */
if (bitData) free(bitData);
if (plane1) free(plane1);
if (plane2) free(plane2);
if (plane3) free(plane3);
- return 0;
+ return code;
}
/*
diff --git a/devices/gdevdm24.c b/devices/gdevdm24.c
index ae7484c..62b7ba8 100644
--- a/devices/gdevdm24.c
+++ b/devices/gdevdm24.c
@@ -64,7 +64,7 @@ dot24_print_page (gx_device_printer *pdev, gp_file *prn_stream, char *init_strin
int y_passes;
int dots_per_space;
int bytes_per_space;
- int skip = 0, lnum = 0, ypass;
+ int skip = 0, lnum = 0, code = 0, ypass;
xres = (int)pdev->x_pixels_per_inch;
yres = (int)pdev->y_pixels_per_inch;
@@ -76,7 +76,7 @@ dot24_print_page (gx_device_printer *pdev, gp_file *prn_stream, char *init_strin
/* We divide by bytes_per_space later on. */
return_error(gs_error_rangecheck);
}
-
+
bits_per_column = (y_high ? 48 : 24);
line_size = gdev_prn_raster (pdev);
in_size = line_size * bits_per_column;
@@ -111,7 +111,9 @@ dot24_print_page (gx_device_printer *pdev, gp_file *prn_stream, char *init_strin
int lcnt;
/* Copy 1 scan line and test for all zero. */
- gdev_prn_copy_scan_lines (pdev, lnum, in, line_size);
+ code = gdev_prn_copy_scan_lines (pdev, lnum, in, line_size);
+ if (code < 0)
+ goto xit;
if (in[0] == 0
&& !memcmp ((char *) in, (char *) in + 1, line_size - 1))
{
@@ -138,27 +140,40 @@ dot24_print_page (gx_device_printer *pdev, gp_file *prn_stream, char *init_strin
/* Copy the rest of the scan lines. */
if (y_high)
{
+ /* NOTE: even though fixed to not ignore return < 0 from gdev_prn_copy_scan_lines, */
+ /* this code seems wrong -- it doesn't seem to match the 'else' method. */
inp = in + line_size;
- for (lcnt = 1; lcnt < 24; lcnt++, inp += line_size)
- if (!gdev_prn_copy_scan_lines (pdev, lnum + lcnt * 2, inp,
- line_size))
+ for (lcnt = 1; lcnt < 24; lcnt++, inp += line_size) {
+ code = gdev_prn_copy_scan_lines (pdev, lnum + lcnt * 2, inp, line_size);
+ if (code < 0)
+ goto xit;
+ if (code == 0)
{
+ /* Pad with lines of zeros. */
memset (inp, 0, (24 - lcnt) * line_size);
break;
}
+ }
inp = in + line_size * 24;
- for (lcnt = 0; lcnt < 24; lcnt++, inp += line_size)
- if (!gdev_prn_copy_scan_lines (pdev, lnum + lcnt * 2 + 1, inp,
- line_size))
+ for (lcnt = 0; lcnt < 24; lcnt++, inp += line_size) {
+ code = gdev_prn_copy_scan_lines (pdev, lnum + lcnt * 2 + 1, inp, line_size);
+ if (code < 0)
+ goto xit;
+ if (code == 0)
{
+ /* Pad with lines of zeros. */
memset (inp, 0, (24 - lcnt) * line_size);
break;
}
+ }
}
else
{
- lcnt = 1 + gdev_prn_copy_scan_lines (pdev, lnum + 1, in + line_size,
+ code = gdev_prn_copy_scan_lines (pdev, lnum + 1, in + line_size,
in_size - line_size);
+ if (code < 0)
+ goto xit;
+ lcnt = code + 1; /* FIXME: why +1 */
if (lcnt < 24)
/* Pad with lines of zeros. */
memset (in + lcnt * line_size, 0, in_size - lcnt * line_size);
@@ -242,10 +257,11 @@ dot24_print_page (gx_device_printer *pdev, gp_file *prn_stream, char *init_strin
gp_fputs ("\f\033@", prn_stream);
gp_fflush (prn_stream);
+xit:
gs_free (pdev->memory, (char *) out, out_size, 1, "dot24_print_page (out)");
gs_free (pdev->memory, (char *) in, in_size, 1, "dot24_print_page (in)");
- return 0;
+ return code;
}
/* Output a single graphics command. */
diff --git a/devices/gdevepsc.c b/devices/gdevepsc.c
index 49e83f0..f6fa2b3 100644
--- a/devices/gdevepsc.c
+++ b/devices/gdevepsc.c
@@ -184,7 +184,7 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
int last_pass;
int dots_per_space;
int bytes_per_space;
- int skip = 0, lnum = 0, pass;
+ int skip = 0, lnum = 0, code = 0, pass;
byte *color_in;
int color_line_size, color_in_size;
@@ -232,7 +232,7 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
if (out)
gs_free(pdev->memory, (char *)out, out_size + 1, 1,
"epsc_print_page(out)");
- return -1;
+ return_error(gs_error_VMerror);
}
/* Initialize the printer and reset the margins. */
@@ -248,7 +248,7 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
"epsc_print_page(in)");
gs_free(pdev->memory, (char *)out, out_size + 1, 1,
"epsc_print_page(out)");
- return (-1);
+ return_error(gs_error_VMerror);
}
} else {
color_in = in;
@@ -263,7 +263,9 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
byte *nextmono = NULL; /* position to map next color */
/* Copy 1 scan line and test for all zero. */
- gdev_prn_copy_scan_lines(pdev, lnum, color_in, color_line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, color_in, color_line_size);
+ if (code < 0)
+ goto xit;
if (color_in[0] == 0 &&
!memcmp((char *)color_in, (char *)color_in + 1,
@@ -283,9 +285,12 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
gp_fprintf(prn_stream, "\033J%c", skip);
/* Copy the rest of the scan lines. */
- lcnt = 1 + gdev_prn_copy_scan_lines(pdev, lnum + 1,
+ code = gdev_prn_copy_scan_lines(pdev, lnum + 1,
color_in + color_line_size,
color_in_size - color_line_size);
+ if (code < 0)
+ goto xit;
+ lcnt = code + 1;
if (lcnt < 8 * y_mult) {
memset((char *)(color_in + lcnt * color_line_size), 0,
@@ -453,13 +458,14 @@ epsc_print_page(gx_device_printer * pdev, gp_file * prn_stream)
/* Eject the page and reinitialize the printer */
gp_fputs("\f\033@", prn_stream);
+xit:
gs_free(pdev->memory, (char *)out, out_size + 1, 1,
"epsc_print_page(out)");
gs_free(pdev->memory, (char *)in, in_size + 1, 1, "epsc_print_page(in)");
if (gx_device_has_color(pdev))
gs_free(pdev->memory, (char *)color_in, color_in_size + 1, 1,
"epsc_print_page(rin)");
- return 0;
+ return code;
}
/* Output a single graphics command. */
diff --git a/devices/gdevepsn.c b/devices/gdevepsn.c
index 3e53883..c69e4b5 100644
--- a/devices/gdevepsn.c
+++ b/devices/gdevepsn.c
@@ -159,22 +159,38 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
/* Note that in_size is a multiple of 8. */
int in_size = line_size * (8 * in_y_mult);
- byte *buf1;
- byte *buf2;
+ byte *buf1 = NULL;
+ byte *buf2 = NULL;
byte *in;
byte *out;
int out_y_mult = (y_24pin ? 3 : 1);
int x_dpi = (int)pdev->x_pixels_per_inch;
- char start_graphics =
- (y_24pin ? graphics_modes_24 : graphics_modes_9)[x_dpi / 60];
- int first_pass = (start_graphics & DD ? 1 : 0);
- int last_pass = first_pass * (y_9pin_high == 2 ? 1 : 2);
int y_passes = (y_9pin_high ? 3 : 1);
int dots_per_space = x_dpi / 10; /* pica space = 1/10" */
int bytes_per_space = dots_per_space * out_y_mult;
int tab_min_pixels = x_dpi * MIN_TAB_10THS / 10;
int skip = 0, lnum = 0, pass, ypass;
+ int code = 0;
+ char start_graphics;
+ int first_pass;
+ int last_pass;
+
+ if (y_24pin) {
+ if (x_dpi / 60 >= sizeof(graphics_modes_24) / sizeof(graphics_modes_24[0])) {
+ return_error(gs_error_rangecheck);
+ }
+ start_graphics = graphics_modes_24[x_dpi / 60];
+ }
+ else {
+ if (x_dpi / 60 >= sizeof(graphics_modes_9) / sizeof(graphics_modes_9[0])) {
+ return_error(gs_error_rangecheck);
+ }
+ start_graphics = graphics_modes_9[x_dpi / 60];
+ }
+ first_pass = (start_graphics & DD ? 1 : 0);
+ last_pass = first_pass * (y_9pin_high == 2 ? 1 : 2);
+
if (bytes_per_space == 0) {
/* This avoids divide by zero later on, bug 701843. */
return_error(gs_error_rangecheck);
@@ -187,12 +203,9 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
/* Check allocations */
- if ( buf1 == 0 || buf2 == 0 )
- { if ( buf1 )
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "eps_print_page(buf1)");
- if ( buf2 )
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "eps_print_page(buf2)");
- return_error(gs_error_VMerror);
+ if ( buf1 == 0 || buf2 == 0 ) {
+ code = gs_error_VMerror;
+ goto xit;
}
/* Initialize the printer and reset the margins. */
@@ -218,7 +231,9 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
int lcnt;
/* Copy 1 scan line and test for all zero. */
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
if ( in_data[0] == 0 &&
!memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
)
@@ -240,7 +255,9 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
}
/* Copy the the scan lines. */
- lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ code = lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if (code < 0)
+ goto xit;
if ( lcnt < 8 * in_y_mult )
{ /* Pad with lines of zeros. */
memset(in + lcnt * line_size, 0,
@@ -255,7 +272,7 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
/* can't print neighboring dots. */
int i;
for ( i = 0; i < line_size * in_y_mult; ++i )
- in_data[i] |= in_data[i + line_size];
+ in[i] |= in[i + line_size];
}
if ( y_9pin_high )
@@ -402,9 +419,14 @@ eps_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high,
gp_fputs(end_string, prn_stream);
gp_fflush(prn_stream);
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "eps_print_page(buf2)");
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "eps_print_page(buf1)");
- return 0;
+xit:
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "eps_print_page(buf1)");
+ if ( buf2 )
+ gs_free(pdev->memory, (char *)buf2, in_size, 1, "eps_print_page(buf2)");
+ if (code < 0)
+ return_error(code);
+ return code;
}
/* Output a single graphics command. */
diff --git a/devices/gdevescp.c b/devices/gdevescp.c
index 0004319..005fa58 100644
--- a/devices/gdevescp.c
+++ b/devices/gdevescp.c
@@ -119,7 +119,7 @@ escp2_print_page(gx_device_printer *pdev, gp_file *prn_stream)
byte *out = buf2;
int skip, lnum, top, bottom, left, width;
- int count, i;
+ int code = 0, count, i;
/*
** Check for valid resolution:
@@ -141,12 +141,9 @@ escp2_print_page(gx_device_printer *pdev, gp_file *prn_stream)
** Check buffer allocations:
*/
- if ( buf1 == 0 || buf2 == 0 )
- { if ( buf1 )
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "escp2_print_page(buf1)");
- if ( buf2 )
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "escp2_print_page(buf2)");
- return_error(gs_error_VMerror);
+ if ( buf1 == 0 || buf2 == 0 ) {
+ code = gs_error_VMerror;
+ goto xit;
}
/*
@@ -218,14 +215,18 @@ escp2_print_page(gx_device_printer *pdev, gp_file *prn_stream)
** Check buffer for 0 data. We can't do this mid-band
*/
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
while ( in_data[0] == 0 &&
!memcmp((char *)in_data, (char *)in_data + 1, line_size - 1) &&
lnum < bottom )
{
lnum++;
skip++;
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
}
if(lnum == bottom ) break; /* finished with this page */
@@ -241,7 +242,9 @@ escp2_print_page(gx_device_printer *pdev, gp_file *prn_stream)
skip = 0;
}
- lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ code = lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if (lcnt < 0)
+ goto xit;
/*
** Check to see if we don't have enough data to fill an entire
@@ -403,7 +406,13 @@ escp2_print_page(gx_device_printer *pdev, gp_file *prn_stream)
gp_fputs("\f\033@", prn_stream);
gp_fflush(prn_stream);
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "escp2_print_page(buf2)");
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "escp2_print_page(buf1)");
- return 0;
+xit:
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "escp2_print_page(buf1)");
+ if ( buf2 )
+ gs_free(pdev->memory, (char *)buf2, in_size, 1, "escp2_print_page(buf2)");
+ if (code < 0)
+ return_error(code);
+
+ return code;
}
diff --git a/devices/gdevgprf.c b/devices/gdevgprf.c
index ff383e5..492b1c2 100644
--- a/devices/gdevgprf.c
+++ b/devices/gdevgprf.c
@@ -372,6 +372,8 @@ gprf_prn_open(gx_device * pdev)
pdev_gprf->icclink = gsicc_alloc_link_dev(pdev_gprf->memory,
profile_struct->device_profile[0], profile_struct->postren_profile,
&rendering_params);
+ if (pdev_gprf->icclink == NULL)
+ code = gs_error_VMerror;
}
return code;
}
diff --git a/devices/gdevhl7x.c b/devices/gdevhl7x.c
index 786449d..1a3e594 100644
--- a/devices/gdevhl7x.c
+++ b/devices/gdevhl7x.c
@@ -108,7 +108,7 @@ typedef struct {
typedef struct {
short previousSize;
- Byte previousData[1500]; /* Size bigger than any possible line */
+ Byte* previousData;
short nbBlankLines;
short nbLinesSent;
short pageWidth;
@@ -139,7 +139,9 @@ static int dumpPage(gx_device_printer * pSource,
ByteList * pCommandList,
Summary * pSummary
);
-static void initSummary(Summary * s,short pw, short ph, short resolution);
+static int initSummary(gx_device_printer* pdev, Summary * s,short pw, short ph, short resolution);
+
+static void freeSummary(gx_device_printer* pdev, Summary * s);
static void resetPreviousData(Summary * s);
@@ -319,6 +321,7 @@ static int
hl7x0_print_page(gx_device_printer *pdev, gp_file *printStream, int ptype,
int dots_per_inch, ByteList *initCommand)
{
+ int code;
/* UTILE*/
/* Command for a formFeed (we can't use strings because of the zeroes...)*/
Byte FormFeed[] = {'@','G',0x00,0x00,0x01,0xFF,'@','F'};
@@ -338,12 +341,17 @@ hl7x0_print_page(gx_device_printer *pdev, gp_file *printStream, int ptype,
/* bool dupset = pdev->Duplex_set >= 0; */
Summary pageSummary;
ByteList commandsBuffer;
- initSummary(&pageSummary,
+ if ( storage == 0 ) /* can't allocate working area */
+ return_error(gs_error_VMerror);
+ code = initSummary(pdev,
+ &pageSummary,
line_size,
num_rows,
x_dpi);
- if ( storage == 0 ) /* can't allocate working area */
- return_error(gs_error_VMerror);
+ if (code < 0) {
+ gs_free(pdev->memory, (char *)storage, storage_size_words, 1, "hl7X0_print_page");
+ return code;
+ }
initByteList(&commandsBuffer, storage, sizeOfBuffer,0 );
/* PLUS A MOI */
if ( pdev->PageCount == 0 )
@@ -358,9 +366,11 @@ hl7x0_print_page(gx_device_printer *pdev, gp_file *printStream, int ptype,
storage + sizeOfBuffer, /* The line buffer is after the dump buffer */
&commandsBuffer,
&pageSummary);
+ if (result < 0)
+ goto xit;
dumpToPrinter(&commandsBuffer,printStream);
- } while (result == DumpContinue);
+ } while (result == DumpContinue); /* NB: at end of page, result will be DumpFinished == 0 */
/* end raster graphics and eject page */
initByteList(&formFeedCommand,
@@ -369,10 +379,12 @@ hl7x0_print_page(gx_device_printer *pdev, gp_file *printStream, int ptype,
sizeof(FormFeed)); /* First free byte */
dumpToPrinter(&formFeedCommand, printStream);
+xit:
/* free temporary storage */
+ freeSummary(pdev, &pageSummary);
gs_free(pdev->memory, (char *)storage, storage_size_words, 1, "hl7X0_print_page");
- return 0; /* If we reach this line, it means there was no error */
+ return result; /* If we reach this line, it means there was no error */
}
/*
@@ -413,14 +425,23 @@ return (((LETTER_WIDTH * resolution/600 - pixWidth) + pixOffset * 2) + 7) / 8;
/*
* First values in a Summary
*/
-static void initSummary(Summary * s,short pw, short ph, short resolution){
+static int initSummary(gx_device_printer* pdev, Summary * s,short pw, short ph, short resolution){
s->previousSize = -1 ;
+ s->previousData = gs_malloc(pdev->memory, pw, 1, "initSummary");
s->nbBlankLines = 1;
s->nbLinesSent = 0;
s->pageWidth = pw; /* In Bytes */
s->pageHeight = ph;
s->horizontalOffset = horizontalOffset( pw * 8,LEFT_MARGIN, resolution) ;
s->resolution = resolution;
+ if (!s->previousData) {
+ return_error(gs_error_VMerror);
+ }
+ return 0;
+}
+
+static void freeSummary(gx_device_printer* pdev, Summary * s) {
+ gs_free(pdev->memory, s->previousData, s->pageWidth, 1, "freeSummary");
}
/*
@@ -445,6 +466,8 @@ static int dumpPage(gx_device_printer * pSource,
short lineNB;
short usefulLength;
short tmpLength;
+ int code = 0;
+
/* Initializations */
/* Make room for size of commands buffer */
pSaveCommandStart = currentPosition(pCommandList);
@@ -454,10 +477,12 @@ static int dumpPage(gx_device_printer * pSource,
for (lineNB = pSummary->nbLinesSent /*ERROR? + nbBlankLines */ ;
lineNB < pSummary->pageHeight ; lineNB ++ ) {
/* Fetch the line and put it into the buffer */
- gdev_prn_copy_scan_lines(pSource,
+ code = gdev_prn_copy_scan_lines(pSource,
lineNB,
pLineTmp,
pSummary->pageWidth);
+ if (code < 0)
+ return code;
usefulLength = stripTrailingBlanks(pLineTmp,pSummary->pageWidth);
if (usefulLength != 0) {
diff --git a/devices/gdevicov.c b/devices/gdevicov.c
index 4f4d7f5..517ca4f 100644
--- a/devices/gdevicov.c
+++ b/devices/gdevicov.c
@@ -37,18 +37,20 @@
static int
cov_write_page(gx_device_printer *pdev, gp_file *file)
{
- int code = 0;
+ int code = 0, ecode = 0;
int raster = gdev_prn_raster(pdev);
int height = pdev->height;
byte *line = gs_alloc_bytes(pdev->memory, raster, "ink coverage plugin buffer");
int y;
uint64_t c_pix = 0, m_pix = 0, y_pix = 0, k_pix = 0, total_pix = 0;
+ if (line == NULL)
+ return gs_error_VMerror;
for (y = 0; y < height; y++) {
byte *row, *end;
- code = gdev_prn_get_bits(pdev, y, line, &row);
- if (code < 0)
+ ecode = gdev_prn_get_bits(pdev, y, line, &row);
+ if (ecode < 0)
break;
end = row + raster;
@@ -90,14 +92,14 @@ cov_write_page(gx_device_printer *pdev, gp_file *file)
}
}
- return 0;
+ return (code > 0) ? ecode : 0;
}
/* cov_write_page2 gave ink coverage values not ratecoverage */
static int cov_write_page_ink(gx_device_printer *pdev, gp_file *file)
{
- int code = 0;
+ int code = 0, ecode = 0;
int raster = gdev_prn_raster(pdev);
int height = pdev->height;
double dc_pix=0;
@@ -109,11 +111,13 @@ static int cov_write_page_ink(gx_device_printer *pdev, gp_file *file)
int y;
uint64_t total_pix = 0;
+ if (line == NULL)
+ return gs_error_VMerror;
for (y = 0; y < height; y++) {
byte *row, *end;
- code = gdev_prn_get_bits(pdev, y, line, &row);
- if (code < 0)
+ ecode = gdev_prn_get_bits(pdev, y, line, &row);
+ if (ecode < 0)
break;
end = row + raster;
@@ -159,7 +163,7 @@ static int cov_write_page_ink(gx_device_printer *pdev, gp_file *file)
}
}
- return 0;
+ return (code > 0) ? ecode : 0;
}
static const gx_device_procs cov_procs =
diff --git a/devices/gdevifno.c b/devices/gdevifno.c
index 31aa514..22d5837 100644
--- a/devices/gdevifno.c
+++ b/devices/gdevifno.c
@@ -281,6 +281,7 @@ inferno_print_page(gx_device_printer *pdev, gp_file *f)
int gsbpl;
ulong u;
ushort us;
+ int code = 0;
inferno_device *bdev = (inferno_device *) pdev;
Rectangle r;
@@ -319,7 +320,10 @@ inferno_print_page(gx_device_printer *pdev, gp_file *f)
* to save all the ldepth lookups.
*/
for(y=0; y<pdev->height; y++) {
- gdev_prn_get_bits(pdev, y, buf, &p);
+
+ code = gdev_prn_get_bits(pdev, y, buf, &p);
+ if (code < 0)
+ goto xit;
for(x=0; x<pdev->width; x++) {
us = (p[2*x]<<8) | p[2*x+1];
@@ -372,12 +376,13 @@ inferno_print_page(gx_device_printer *pdev, gp_file *f)
return_error(gs_error_Fatal);
}
}
- gs_free_object(bdev->memory, buf, "inferno line buffer");
if(writeimageblock(w, nil, 0, bdev->memory) == ERROR) {
return_error(gs_error_Fatal);
}
+xit:
+ gs_free_object(bdev->memory, buf, "inferno line buffer");
- return 0;
+ return code;
}
/*
diff --git a/devices/gdevimgn.c b/devices/gdevimgn.c
index 7340c8d..7c707bd 100644
--- a/devices/gdevimgn.c
+++ b/devices/gdevimgn.c
@@ -379,6 +379,7 @@ imagen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* page totals */
int totalBlankSwatches;
int totalGreySwatches;
+ int code = 0;
/* ----------------------------------------- */
/* Start of routine */
@@ -406,8 +407,8 @@ imagen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
swatchMap = (byte *)gs_malloc(pdev->memory, BIGSIZE,swatchCount / BIGSIZE + 1,
"imagen_print_page(swatchMap)" );
- if ( in == 0 || out == 0 )
- return -1;
+ if ( in == 0 || out == 0 || swatchMap == 0)
+ goto xit;
/* Initialize the page */
iWrite(prn_stream,iPAGE);
@@ -450,7 +451,9 @@ imagen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
} /* for temp */
/* get one line */
- gdev_prn_copy_scan_lines(pdev, lnum + swatchLine, in, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum + swatchLine, in, line_size);
+ if (code < 0)
+ goto xit;
DebugMsg(5,"Got scan line %d ", lnum + swatchLine);
DebugMsg(5,"line %d \n", swatchLine);
@@ -553,6 +556,7 @@ imagen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
gp_fflush(prn_stream);
+xit:
gs_free(pdev->memory, (char *)out, TotalBytesPerSw, swatchCount+1, "imagen_print_page(out)");
gs_free(pdev->memory, (char *)swatchMap, BIGSIZE, swatchCount / BIGSIZE + 1,
"imagen_print_page(swatchMap)" );
@@ -564,6 +568,6 @@ imagen_print_page(gx_device_printer *pdev, gp_file *prn_stream)
DebugMsg(1,"%s\n","End of imagen_print_page");
/* ----------------------------------------- */
- return 0;
+ return code;
} /* imagen_print_page */
diff --git a/devices/gdevjbig2.c b/devices/gdevjbig2.c
index ce85aa2..0555081 100644
--- a/devices/gdevjbig2.c
+++ b/devices/gdevjbig2.c
@@ -89,7 +89,7 @@ jbig2_print_page(gx_device_printer * pdev, gp_file * prn_stream)
swrite_file(&fstrm, prn_stream, fbuf, fbuf_size);
s_init(&cstrm, mem);
s_std_init(&cstrm, jbuf, jbuf_size, &s_filter_write_procs,
- s_mode_write);
+ s_devices/gdevescp.cmode_write);
cstrm.state = (stream_state *) & state;
cstrm.procs.process = state.templat->process;
cstrm.strm = &fstrm;
@@ -108,7 +108,9 @@ jbig2_print_page(gx_device_printer * pdev, gp_file * prn_stream)
code = gs_note_error(gs_error_ioerror);
goto done;
}
- gdev_prn_get_bits(pdev, lnum, in, &data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &data);
+ if (code < 0)
+ goto done;
sputs(&cstrm, data, state.stride, &ignore_used);
}
diff --git a/devices/gdevjpx.c b/devices/gdevjpx.c
index 0ba4e1a..e38f540 100644
--- a/devices/gdevjpx.c
+++ b/devices/gdevjpx.c
@@ -209,7 +209,9 @@ jpx_print_page(gx_device_printer * pdev, gp_file * prn_stream)
code = gs_note_error(gs_error_ioerror);
goto done;
}
- gdev_prn_get_bits(pdev, lnum, in, &data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &data);
+ if (code < 0)
+ goto done;
sputs(&cstrm, data, state.stride, &ignore_used);
}
diff --git a/devices/gdevl31s.c b/devices/gdevl31s.c
index 0871920..b21b18c 100644
--- a/devices/gdevl31s.c
+++ b/devices/gdevl31s.c
@@ -180,6 +180,8 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream, int num
gs_memory_t *mem = pdev->memory;
byte *in = (byte *)gs_malloc(mem, line_size, 1, "lj3100sw_print_page");
byte *data;
+ int ecode = 0;
+
if (in == 0)
return_error(gs_error_VMerror);
if (gdev_prn_file_is_new(pdev)) {
@@ -211,7 +213,10 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream, int num
int count = 0;
int bit_index = 0;
uint tmp = 0;
- gdev_prn_get_bits(pdev, i, in, &data);
+
+ ecode = gdev_prn_get_bits(pdev, i, in, &data);
+ if (ecode < 0)
+ goto xit;
for (j = 0; j <= printer_width; j++) {
int xoffset = (printer_width - paper_width) / 2;
int newcolor = 0;
@@ -261,8 +266,9 @@ lj3100sw_print_page_copies(gx_device_printer *pdev, gp_file *prn_stream, int num
for (i = 0; i < 4 * ppdev->NumCopies; i++)
lj3100sw_output_section_header(prn_stream, 54, 0, 0);
+xit:
gs_free(mem, (char *)in, line_size, 1, "lj3100sw_print_page");
- return 0;
+ return ecode;
}
static int
diff --git a/devices/gdevlbp8.c b/devices/gdevlbp8.c
index 5b99cf2..3136772 100644
--- a/devices/gdevlbp8.c
+++ b/devices/gdevlbp8.c
@@ -108,6 +108,7 @@ can_print_page(gx_device_printer *pdev, gp_file *prn_stream,
char *out_data;
int last_line_nro = 0;
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
+ int code = 0;
data = (char *)gs_alloc_bytes(pdev->memory,
line_size*2,
@@ -124,8 +125,10 @@ can_print_page(gx_device_printer *pdev, gp_file *prn_stream,
for ( lnum = 0; lnum < pdev->height; lnum++ ) {
char *end_data = data + line_size;
- gdev_prn_copy_scan_lines(pdev, lnum,
- (byte *)data, line_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum,
+ (byte *)data, line_size);
+ if (code < 0)
+ goto xit;
/* Mask off 1-bits beyond the line width. */
end_data[-1] &= rmask;
/* Remove trailing 0s. */
@@ -199,9 +202,10 @@ can_print_page(gx_device_printer *pdev, gp_file *prn_stream,
if (end != NULL)
(void)gp_fwrite(end, end_size, 1, prn_stream);
+xit:
gs_free_object(pdev->memory, data, "lbp8_line_buffer");
- return 0;
+ return code;
}
/* Print an LBP-8 page. */
diff --git a/devices/gdevlj56.c b/devices/gdevlj56.c
index 4a473e0..6199e5b 100644
--- a/devices/gdevlj56.c
+++ b/devices/gdevlj56.c
@@ -192,7 +192,7 @@ ljet5_print_page(gx_device_printer * pdev, gp_file * prn_stream)
code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) line, line_size);
if (code < 0)
- goto fin;
+ goto done;
px_put_us(s, lnum);
PX_PUT_LIT(s, line_header);
ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words,
@@ -202,7 +202,6 @@ ljet5_print_page(gx_device_printer * pdev, gp_file * prn_stream)
}
/* Finish up. */
- fin:
spputc(s, pxtEndImage);
spputc(s, pxtEndPage);
sflush(s);
diff --git a/devices/gdevlp8k.c b/devices/gdevlp8k.c
index 55af94d..58ae070 100644
--- a/devices/gdevlp8k.c
+++ b/devices/gdevlp8k.c
@@ -193,18 +193,13 @@ lp8000_print_page(gx_device_printer *pdev, gp_file *prn_stream)
byte *out = buf2;
int lnum, top, bottom, left, width;
- int count, left1, left2, left0;
+ int code = 0, count, left1, left2, left0;
/* Check memory allocations */
- if ( buf1 == 0 || buf2 == 0 )
- { if ( buf1 )
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "lp8000_print_page(buf1)");
-
- if ( buf2 )
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "lp8000_print_page(buf2)");
-
- return_error(gs_error_VMerror);
+ if ( buf1 == 0 || buf2 == 0 ) {
+ code = gs_error_VMerror;
+ goto xit;
}
/* Initialize the printer */
@@ -265,19 +260,25 @@ starting X value of the printer line.
** Check buffer for 0 data.
*/
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
while ( in_data[0] == 0 &&
!memcmp((char *)in_data, (char *)in_data + 1, line_size - 1) &&
lnum < bottom )
{
lnum++;
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
}
if(lnum == bottom ) break;
/* finished with this page */
- (void)gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ code = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if (code < 0)
+ goto xit;
inp = in + left;
in_end = inp + width;
@@ -397,7 +398,14 @@ Y coordinate of the printer equals (lnum - 60)
gp_fflush(prn_stream);
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "lp8000_print_page(buf2)");
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "lp8000_print_page(buf1)");
- return 0;
+xit:
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "lp8000_print_page(buf1)");
+ if ( buf2 )
+ gs_free(pdev->memory, (char *)buf2, in_size, 1, "lp8000_print_page(buf2)");
+
+ if (code < 0)
+ return_error(code);
+
+ return code;
}
diff --git a/devices/gdevlxm.c b/devices/gdevlxm.c
index 4b0f26e..fe577c3 100644
--- a/devices/gdevlxm.c
+++ b/devices/gdevlxm.c
@@ -146,6 +146,7 @@ lxm5700m_print_page(gx_device_printer *pdev, gp_file *prn_stream)
int lnum,minX, maxX, i, l, highestX, leastX, extent;
int direction = RIGHTWARD;
int lastY = 0;
+ int code = 0;
int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
/* Note that in_size is a multiple of 8. */
@@ -158,12 +159,8 @@ lxm5700m_print_page(gx_device_printer *pdev, gp_file *prn_stream)
/* Check allocations */
if ( buf1 == 0 || swipeBuf == 0 ) {
- if ( buf1 )
-quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "lxm_print_page(buf1)");
- if ( swipeBuf )
- gs_free(pdev->memory, (char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
- return_error(gs_error_VMerror);
+ code = gs_error_VMerror;
+ goto xit;
}
{ /* Initialize the printer and reset the margins. */
@@ -186,7 +183,9 @@ quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
for (l=lnum; l<pdev->height; l++) {
/* Copy 1 scan line and test for all zero. */
- gdev_prn_get_bits(pdev, l, in, &in_data);
+ code = gdev_prn_get_bits(pdev, l, in, &in_data);
+ if (code < 0)
+ goto xit;
if ( in_data[0] != 0 ||
memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
) {
@@ -211,7 +210,9 @@ quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
}
/* Copy the the scan lines. */
- lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ code = lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
+ if (code < 0)
+ goto xit;
if ( lcnt < swipeHeight ) {
/* Pad with lines of zeros. */
memset(in + lcnt * line_size, 0,
@@ -251,7 +252,7 @@ quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
size_t outp_offset = outp - swipeBuf;\
size_t swipeBuf_size_new = swipeBuf_size * 2;\
byte* swipeBuf_new = gs_malloc(pdev->memory, swipeBuf_size_new, 1, "lxm_print_page(swipeBuf_new)");\
- if (!swipeBuf_new) goto quit_ignomiously;\
+ if (!swipeBuf_new) { code = gs_error_VMerror; goto xit; }\
memcpy(swipeBuf_new, swipeBuf, swipeBuf_size);\
gs_free(pdev->memory, swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");\
swipeBuf_size = swipeBuf_size_new;\
@@ -372,9 +373,14 @@ quit_ignomiously: /* and a goto into an if statement is pretty ignomious! */
}
gp_fflush(prn_stream);
- gs_free(pdev->memory, (char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "lxm_print_page(buf1)");
- return 0;
+xit:
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "lxm_print_page(buf1)");
+ if ( swipeBuf )
+ gs_free(pdev->memory, (char *)swipeBuf, swipeBuf_size, 1, "lxm_print_page(swipeBuf)");
+ if (code < 0)
+ return_error(code);
+ return code;
}
/*
diff --git a/devices/gdevmgr.c b/devices/gdevmgr.c
index 07761da..c6b6605 100644
--- a/devices/gdevmgr.c
+++ b/devices/gdevmgr.c
@@ -131,18 +131,20 @@ mgr_begin_page(gx_device_mgr *bdev, gp_file *pstream, mgr_cursor *pcur)
return 0;
}
-/* Advance to the next row. Return 0 if more, 1 if done. */
+/* Advance to the next row. Return 0 if more, 1 if done. <0 if error */
static int
mgr_next_row(mgr_cursor *pcur)
-{ if ( pcur->lnum >= pcur->dev->height )
+{ int code = 0;
+
+ if ( pcur->lnum >= pcur->dev->height )
{ gs_free(((gx_device_printer *)pcur->dev)->memory,
(char *)pcur->data, pcur->line_size, 1,
"mgr_next_row(done)");
return 1;
- }
- gdev_prn_copy_scan_lines((gx_device_printer *)pcur->dev,
+ }
+ code = gdev_prn_copy_scan_lines((gx_device_printer *)pcur->dev,
pcur->lnum++, pcur->data, pcur->line_size);
- return 0;
+ return code < 0 ? code : 0;
}
/* ------ Individual page printing routines ------ */
@@ -219,6 +221,8 @@ mgrN_print_page(gx_device_printer *pdev, gp_file *pstream)
if ( bdev->mgr_depth != 8 )
data = (byte *)gs_malloc(pdev->memory, mgr_line_size, 1, "mgrN_print_page");
+ if (data == NULL)
+ return_error(gs_error_VMerror);
while ( !(code = mgr_next_row(&cur)) )
{
@@ -306,6 +310,8 @@ cmgrN_print_page(gx_device_printer *pdev, gp_file *pstream)
}
mgr_line_size = mgr_wide / (8 / bdev->mgr_depth);
data = (byte *)gs_malloc(pdev->memory, mgr_line_size, 1, "cmgrN_print_page");
+ if (data == NULL)
+ return_error(gs_error_VMerror);
if ( bdev->mgr_depth == 8 ) {
memset( table, 0, sizeof(table) );
diff --git a/devices/gdevn533.c b/devices/gdevn533.c
index 5130bd3..3572036 100644
--- a/devices/gdevn533.c
+++ b/devices/gdevn533.c
@@ -163,7 +163,7 @@ nwp533_close(gx_device *dev)
static int
nwp533_print_page(gx_device_printer *dev, gp_file *prn_stream)
{
- int lnum;
+ int lnum, code = 0;
int line_size = gdev_mem_bytes_per_scan_line(dev);
byte *in;
int printer_file;
@@ -174,6 +174,8 @@ nwp533_print_page(gx_device_printer *dev, gp_file *prn_stream)
line_size += 4 - (line_size % 4);
}
in = (byte *) gs_malloc(dev->memory, line_size, 1, "nwp533_output_page(in)");
+ if (in == NULL)
+ return_error(gs_error_VMerror);
restart:
if(ioctl(printer_file, LBIOCSTOP, 0) < 0)
{
@@ -186,7 +188,9 @@ nwp533_print_page(gx_device_printer *dev, gp_file *prn_stream)
for ( lnum = 0; lnum < dev->height; lnum++)
{
- gdev_prn_copy_scan_lines(prn_dev, lnum, in, line_size);
+ code = gdev_prn_copy_scan_lines(prn_dev, lnum, in, line_size);
+ if (code < 0)
+ goto xit;
if(write(printer_file, in, line_size) != line_size)
{
perror("Writting to output");
@@ -201,7 +205,8 @@ nwp533_print_page(gx_device_printer *dev, gp_file *prn_stream)
perror("Starting print");
return_error(gs_error_ioerror);
}
+xit:
gs_free(dev->memory, in, line_size, 1, "nwp533_output_page(in)");
- return 0;
+ return code;
}
diff --git a/devices/gdevokii.c b/devices/gdevokii.c
index 97a1c3b..3350f6d 100644
--- a/devices/gdevokii.c
+++ b/devices/gdevokii.c
@@ -111,6 +111,7 @@ okiibm_print_page1(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high
int y_passes;
int skip = 0, lnum = 0, pass, ypass;
int y_step = 0;
+ int code = 0;
x_dpi = pdev->x_pixels_per_inch;
if (x_dpi / 60 >= sizeof(graphics_modes_9)/sizeof(graphics_modes_9[0])) {
@@ -132,12 +133,9 @@ okiibm_print_page1(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high
y_step = 0;
/* Check allocations */
- if ( buf1 == 0 || buf2 == 0 )
- { if ( buf1 )
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "okiibm_print_page(buf1)");
- if ( buf2 )
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "okiibm_print_page(buf2)");
- return_error(gs_error_VMerror);
+ if ( buf1 == 0 || buf2 == 0 ) {
+ code = gs_error_VMerror;
+ goto xit;
}
/* Initialize the printer. */
@@ -153,7 +151,9 @@ okiibm_print_page1(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high
int lcnt;
/* Copy 1 scan line and test for all zero. */
- gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
+ if (code < 0)
+ goto xit;
if ( in_data[0] == 0 &&
!memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
)
@@ -264,8 +264,13 @@ okiibm_print_page1(gx_device_printer *pdev, gp_file *prn_stream, int y_9pin_high
gp_fwrite(end_string, 1, end_length, prn_stream);
gp_fflush(prn_stream);
- gs_free(pdev->memory, (char *)buf2, in_size, 1, "okiibm_print_page(buf2)");
- gs_free(pdev->memory, (char *)buf1, in_size, 1, "okiibm_print_page(buf1)");
+xit:
+ if ( buf1 )
+ gs_free(pdev->memory, (char *)buf1, in_size, 1, "okiibm_print_page(buf1)");
+ if ( buf2 )
+ gs_free(pdev->memory, (char *)buf2, in_size, 1, "okiibm_print_page(buf2)");
+ if (code < 0)
+ return_error(code);
return 0;
}
diff --git a/devices/gdevpbm.c b/devices/gdevpbm.c
index 647349e..412d010 100644
--- a/devices/gdevpbm.c
+++ b/devices/gdevpbm.c
@@ -1054,6 +1054,8 @@ pnmcmyk_print_page(gx_device_printer *pdev, gp_file *pstream)
!strncmp(pdev->fname, "/dev/null", min(strlen(pdev->fname), 9));
int (*row_proc) (gx_device_printer *, byte *, int, gp_file *);
+ if (data == NULL)
+ return_error(gs_error_VMerror);
if (!output_is_nul) {
if (gp_fprintf(pstream, "P5\n") < 0) { /* PGM raw */
code = gs_note_error(gs_error_ioerror);
diff --git a/devices/gdevpdfimg.c b/devices/gdevpdfimg.c
index bbeefc8..998574c 100644
--- a/devices/gdevpdfimg.c
+++ b/devices/gdevpdfimg.c
@@ -271,6 +271,10 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
profile_struct->device_profile[0], profile_struct->postren_profile,
&rendering_params);
}
+ if (pdf_dev->icclink == NULL) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
+ return_error(gs_error_VMerror);
+ }
/* If it is identity, release it now and set link to NULL */
if (pdf_dev->icclink->is_identity) {
pdf_dev->icclink->procs.free_link(pdf_dev->icclink);
@@ -281,8 +285,10 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
/* Set up the stream and insert the file header */
pdf_dev->strm = s_alloc(pdf_dev->memory->non_gc_memory, "pdfimage_open_temp_stream(strm)");
- if (pdf_dev->strm == 0)
+ if (pdf_dev->strm == 0) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
return_error(gs_error_VMerror);
+ }
pdf_dev->strm_buf = gs_alloc_bytes(pdf_dev->memory->non_gc_memory, pdf_dev->width * (pdf_dev->color_info.depth / 8),
"pdfimage_open_temp_stream(strm_buf)");
if (pdf_dev->strm_buf == 0) {
@@ -290,6 +296,7 @@ static int gdev_pdf_image_begin_page(gx_device_pdf_image *pdf_dev,
gs_free_object(pdf_dev->memory->non_gc_memory, pdf_dev->strm,
"pdfimage_open_temp_stream(strm)");
pdf_dev->strm = 0;
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
return_error(gs_error_VMerror);
}
swrite_file(pdf_dev->strm, pdf_dev->file, pdf_dev->strm_buf, pdf_dev->width * (pdf_dev->color_info.depth / 8));
@@ -1276,6 +1283,10 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev,
profile_struct->device_profile[0], profile_struct->postren_profile,
&rendering_params);
}
+ if (pdf_dev->icclink == NULL) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
+ return_error(gs_error_VMerror);
+ }
/* If it is identity, release it now and set link to NULL */
if (pdf_dev->icclink->is_identity) {
pdf_dev->icclink->procs.free_link(pdf_dev->icclink);
@@ -1286,8 +1297,10 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev,
/* Set up the stream and insert the file header */
pdf_dev->strm = s_alloc(pdf_dev->memory->non_gc_memory, "pdfimage_open_temp_stream(strm)");
- if (pdf_dev->strm == 0)
+ if (pdf_dev->strm == 0) {
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
return_error(gs_error_VMerror);
+ }
pdf_dev->strm_buf = gs_alloc_bytes(pdf_dev->memory->non_gc_memory, 512,
"pdfimage_open_temp_stream(strm_buf)");
if (pdf_dev->strm_buf == 0) {
@@ -1295,6 +1308,7 @@ static int gdev_PCLm_begin_page(gx_device_pdf_image *pdf_dev,
gs_free_object(pdf_dev->memory->non_gc_memory, pdf_dev->strm,
"pdfimage_open_temp_stream(strm)");
pdf_dev->strm = 0;
+ gs_free_object(pdf_dev->memory->non_gc_memory, page, "pdfimage create new page");
return_error(gs_error_VMerror);
}
swrite_file(pdf_dev->strm, pdf_dev->file, pdf_dev->strm_buf, 512);
diff --git a/devices/gdevperm.c b/devices/gdevperm.c
index fe2295e..f2a5e38 100644
--- a/devices/gdevperm.c
+++ b/devices/gdevperm.c
@@ -135,8 +135,8 @@ perm_print_page(gx_device_printer *pdev, gp_file *pstream)
gx_device_perm_t * const dev = (gx_device_perm_t *)pdev;
int ncomp = dev->num_std_colorant_names;
int raw_raster = pdev->width * ncomp;
- byte *raw_line;
- byte *cooked_line;
+ byte *raw_line = NULL;
+ byte *cooked_line = NULL;
byte *row;
int code = 0;
int mode = dev->mode;
@@ -145,9 +145,15 @@ perm_print_page(gx_device_printer *pdev, gp_file *pstream)
fprintf(pstream, "P6\n%d %d\n255\n", dev->width, dev->height);
raw_line = gs_alloc_bytes(pdev->memory, raw_raster, "perm_print_page");
cooked_line = gs_alloc_bytes(pdev->memory, dev->width * 3, "perm_print_page");
+ if (raw_line == NULL || cooked_line == NULL) {
+ gs_free_object(pdev->memory, raw_line, "perm_print_page");
+ return_error(gs_error_VMerror);
+ }
for (y = 0; y < dev->height; y++) {
int x;
code = gdev_prn_get_bits(pdev, y, raw_line, &row);
+ if (code < 0)
+ break;
for (x = 0; x < dev->width; x++) {
int c, m, y, k;
int r, g, b;
diff --git a/devices/gdevphex.c b/devices/gdevphex.c
index f5fac8a..f3ca504 100644
--- a/devices/gdevphex.c
+++ b/devices/gdevphex.c
@@ -947,8 +947,8 @@ static void ScheduleMiddle( SCHEDUL *p );
static void ScheduleTrailing( SCHEDUL *p );
static void ScheduleBand( SCHEDUL *p, int mask );
-static void RenderPage( RENDER *p );
-static void RenderLine( RENDER *p, int line );
+static int RenderPage( RENDER *p );
+static int RenderLine( RENDER *p, int line );
static int IsScanlineEmpty( RENDER *p, byte *line );
static int RleCompress( RAWLINE *raw, int min, int max, byte *rle_data );
@@ -1682,6 +1682,7 @@ static int photoex_print_page( PDEV *device, gp_file *stream )
{
int pixels; /* Length of the line */
int x; /* Work vars */
+int code = 0;
EDEV *dev; /* Our device */
RENDER *render; /* Rendering info */
@@ -1791,7 +1792,9 @@ double psize;
/* Render the page and send image data to printer */
- RenderPage( render );
+ code = RenderPage( render );
+ if (code < 0)
+ goto xit;
/* Eject the paper, reset printer */
@@ -1799,10 +1802,10 @@ double psize;
SendReset( stream );
/* Release the memory and return */
-
+xit:
gs_free( dev->memory, render->dbuff, pixels, sizeof( long ), "PhotoEX" );
gs_free( dev->memory, render, 1, sizeof( RENDER ), "PhotoEX" );
- return( 0 );
+ return( code );
}
/*
@@ -1810,7 +1813,7 @@ double psize;
* ~~~~~~~~~~~~~~
*/
-static void RenderPage( RENDER *p )
+static int RenderPage( RENDER *p )
{
int last_done; /* The last line rendered */
int last_need; /* The largest line number we need */
@@ -1819,6 +1822,7 @@ int last_band; /* Indicates the last band */
int min, max; /* Min/max active bytes in a raw line */
int phase; /* 1440dpi X weave offset */
int i, j, l, col;
+int code = 0;
p->htone_thold = HalftoneThold( p );
p->htone_last = -1 - p->htone_thold;
@@ -1842,7 +1846,11 @@ int i, j, l, col;
last_need = last_done;
for ( i = NOZZLES-1 ; i >= 0 && p->schedule.head[ i ] == -1 ; i-- );
if ( i >= 0 ) last_need = p->schedule.head[ i ];
- while ( last_need > last_done ) RenderLine( p, ++last_done );
+ while ( last_need > last_done ) {
+ code = RenderLine( p, ++last_done );
+ if (code < 0)
+ return code; /* punt */
+ }
/* Now loop through the colours and build the data stream */
@@ -1932,6 +1940,8 @@ int i, j, l, col;
move_down += p->schedule.down;
} while ( ! last_band );
+
+ return code;
}
/*
@@ -1944,14 +1954,16 @@ int i, j, l, col;
* When it sees a nonempty line again, it restarts the renderer.
*/
-static void RenderLine( RENDER *p, int line )
+static int RenderLine( RENDER *p, int line )
{
byte *data;
-int i;
+int i, code = 0;
/* Get the line from Ghostscript and see if its empty */
- gdev_prn_get_bits( (PDEV *) p->dev, line, p->dbuff, &data );
+ code = gdev_prn_get_bits( (PDEV *) p->dev, line, p->dbuff, &data );
+ if (code < 0)
+ return code;
if ( IsScanlineEmpty( p, data ) ) {
@@ -1994,6 +2006,7 @@ int i;
HalftoneLine( p, line, data );
p->htone_last = line;
}
+ return 0;
}
/*
diff --git a/devices/gdevpjet.c b/devices/gdevpjet.c
index e794b0a..d9fc76f 100644
--- a/devices/gdevpjet.c
+++ b/devices/gdevpjet.c
@@ -99,9 +99,10 @@ pj_common_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_origin,
{
int line_size;
int data_size;
- byte *data;
- byte *plane_data;
- byte *temp;
+ byte *data = NULL;
+ byte *plane_data = NULL;
+ byte *temp = NULL;
+ int code = 0;
/* We round up line_size to a multiple of 8 bytes */
/* because that's the unit of transposition from pixels to planes. */
@@ -154,8 +155,10 @@ pj_common_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_origin,
int num_blank_lines = 0;
for ( lnum = 0; lnum < pdev->height; lnum++ )
{ byte *end_data = data + line_size;
- gdev_prn_copy_scan_lines(pdev, lnum,
+ code = gdev_prn_copy_scan_lines(pdev, lnum,
(byte *)data, line_size);
+ if (code < 0)
+ goto xit;
/* Remove trailing 0s. */
while ( end_data > data && end_data[-1] == 0 )
end_data--;
@@ -223,11 +226,12 @@ pj_common_print_page(gx_device_printer *pdev, gp_file *prn_stream, int y_origin,
/* end the page */
gp_fputs(end_page, prn_stream);
+xit:
gs_free(pdev->memory, (char *)data, data_size, 1, "paintjet_print_page(data)");
gs_free(pdev->memory, (char *)plane_data, line_size * 3, 1, "paintjet_print_page(plane_data)");
gs_free(pdev->memory, temp, line_size * 2, 1, "paintjet_print_page(temp)");
- return 0;
+ return code;
}
/*
diff --git a/devices/gdevpsim.c b/devices/gdevpsim.c
index 3c85c31..7a194c6 100644
--- a/devices/gdevpsim.c
+++ b/devices/gdevpsim.c
@@ -143,7 +143,7 @@ static int
psmono_print_page(gx_device_printer * pdev, gp_file * prn_stream)
{
int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
- int lnum;
+ int lnum, code = 0;
byte *line = gs_alloc_bytes(pdev->memory, line_size, "psmono_print_page");
byte invert = (pdev->color_info.depth == 1 ? 0xff : 0);
gx_device_pswrite_common_t pswrite_common;
@@ -167,7 +167,9 @@ psmono_print_page(gx_device_printer * pdev, gp_file * prn_stream)
int left = line_size;
byte *data;
- gdev_prn_get_bits(pdev, lnum, line, &data);
+ code = gdev_prn_get_bits(pdev, lnum, line, &data);
+ if (code < 0)
+ goto xit;
p = data;
/* Loop invariant: p + left = data + line_size. */
#define min_repeat_run 10
@@ -216,10 +218,11 @@ psmono_print_page(gx_device_printer * pdev, gp_file * prn_stream)
/* Clean up and return. */
fputs("\n", prn_stream);
psw_write_page_trailer(prn_stream, 1, true);
+xit:
gs_free_object(pdev->memory, line, "psmono_print_page");
if (ferror(prn_stream))
return_error(gs_error_ioerror);
- return 0;
+ return code;
}
/* Close the file. */
@@ -307,7 +310,7 @@ psrgb_print_page(gx_device_printer * pdev, gp_file * prn_stream)
int width = pdev->width;
byte *lbuf = gs_alloc_bytes(mem, width * 3,
"psrgb_print_page(lbuf)");
- int lnum;
+ int lnum, code = 0;
stream fs, a85s, rls;
stream_A85E_state a85state;
stream_RLE_state rlstate;
@@ -354,7 +357,9 @@ psrgb_print_page(gx_device_printer * pdev, gp_file * prn_stream)
byte *data;
int i, c;
- gdev_prn_get_bits(pdev, lnum, lbuf, &data);
+ code = gdev_prn_get_bits(pdev, lnum, lbuf, &data);
+ if (code < 0)
+ goto xit;
for (c = 0; c < 3; ++c) {
const byte *p;
@@ -369,7 +374,10 @@ psrgb_print_page(gx_device_printer * pdev, gp_file * prn_stream)
sflush(&fs);
fputs("\n", prn_stream);
psw_write_page_trailer(prn_stream, 1, true);
+xit:
gs_free_object(mem, lbuf, "psrgb_print_page(lbuf)");
+ if (code < 0)
+ return_error(code);
if (ferror(prn_stream))
return_error(gs_error_ioerror);
return 0;
diff --git a/devices/gdevrinkj.c b/devices/gdevrinkj.c
index cc144d7..509edd0 100644
--- a/devices/gdevrinkj.c
+++ b/devices/gdevrinkj.c
@@ -818,6 +818,9 @@ rinkj_add_lut(rinkj_device *rdev, rinkj_lutset *lutset, char plane, gp_file *f)
if (n_graph < 0 || n_graph > 256)
return -1;
chain = (rinkj_lutchain *)gs_alloc_bytes(rdev->memory, sizeof(rinkj_lutchain), "rinkj_add_lut");
+ if (chain == NULL) {
+ return -1;
+ }
chain->next = NULL;
chain->n_graph = n_graph;
chain->graph_x = (double *)gs_alloc_bytes(rdev->memory, sizeof(double) * n_graph, "rinkj_add_lut");
@@ -972,14 +975,23 @@ rinkj_write_image_data(gx_device_printer *pdev, RinkjDevice *cmyk_dev)
n_planes = n_planes_in + rdev->separation_names.num_names;
if_debug1m('r', rdev->memory, "[r]n_planes = %d\n", n_planes);
xsb = pdev->width;
- for (i = 0; i < n_planes_out; i++)
+ for (i = 0; i < n_planes_out; i++) {
plane_data[i] = gs_alloc_bytes(pdev->memory, xsb, "rinkj_write_image_data");
-
+ if (plane_data[i] == NULL) {
+ while (--i >= 0)
+ gs_free_object(pdev->memory, plane_data[i], "rinkj_write_image_data");
+ return_error(gs_error_VMerror);
+ }
+ }
if (rdev->icc_link != NULL) {
cache = (rinkj_color_cache_entry *)gs_alloc_bytes(pdev->memory, RINKJ_CCACHE_SIZE * sizeof(rinkj_color_cache_entry), "rinkj_write_image_data");
- if (cache == NULL)
- return gs_note_error(gs_error_VMerror);
+ if (cache == NULL) {
+ /* i == n_planes_out from above */
+ while (--i >= 0)
+ gs_free_object(pdev->memory, plane_data[i], "rinkj_write_image_data");
+ return_error(gs_error_VMerror);
+ }
/* Set up cache so that none of the keys will hit. */
@@ -999,11 +1011,15 @@ rinkj_write_image_data(gx_device_printer *pdev, RinkjDevice *cmyk_dev)
split_plane_data[6] = plane_data[3];
line = gs_alloc_bytes(pdev->memory, raster, "rinkj_write_image_data");
+ if (line == NULL)
+ goto xit;
for (y = 0; y < pdev->height; y++) {
byte *row;
int x;
code = gdev_prn_get_bits(pdev, y, line, &row);
+ if (code < 0)
+ goto xit;
if (rdev->icc_link == NULL) {
int rowix = 0;
@@ -1115,6 +1131,7 @@ rinkj_write_image_data(gx_device_printer *pdev, RinkjDevice *cmyk_dev)
}
rinkj_device_write(cmyk_dev, NULL);
+xit:
for (i = 0; i < n_planes_in; i++)
gs_free_object(pdev->memory, plane_data[i], "rinkj_write_image_data");
gs_free_object(pdev->memory, line, "rinkj_write_image_data");
diff --git a/devices/gdevsppr.c b/devices/gdevsppr.c
index 144187e..ee3c581 100644
--- a/devices/gdevsppr.c
+++ b/devices/gdevsppr.c
@@ -115,7 +115,8 @@ sparc_print_page(gx_device_printer *pdev, FILE *prn)
struct lpvi_page lpvipage;
struct lpvi_err lpvierr;
char *out_buf;
- int out_size;
+ int out_size, code = 0;
+
if (ioctl(fileno(prn),LPVIIOC_GETPAGE,&lpvipage)!=0)
{
errprintf(pdev->memory, "sparc_print_page: LPVIIOC_GETPAGE failed\n");
@@ -132,7 +133,12 @@ sparc_print_page(gx_device_printer *pdev, FILE *prn)
}
out_size=lpvipage.bitmap_width*lpvipage.page_length;
out_buf=gs_malloc(pdev->memory, out_size,1,"sparc_print_page: out_buf");
- gdev_prn_copy_scan_lines(pdev,0,out_buf,out_size);
+ if (out_buf == NULL)
+ return_error(gs_error_VMerror);
+
+ code = gdev_prn_copy_scan_lines(pdev,0,out_buf,out_size);
+ if (code < 0)
+ goto xit;
while (write(fileno(prn),out_buf,out_size)!=out_size)
{
if (ioctl(fileno(prn),LPVIIOC_GETERR,&lpvierr)!=0)
@@ -182,6 +188,7 @@ sparc_print_page(gx_device_printer *pdev, FILE *prn)
errprintf(pdev->memory, "OK.\n");
warning=0;
}
+xit:
gs_free(pdev->memory, out_buf,out_size,1,"sparc_print_page: out_buf");
- return 0;
+ return code;
}
diff --git a/devices/gdevstc.c b/devices/gdevstc.c
index 9040f06..951ded0 100644
--- a/devices/gdevstc.c
+++ b/devices/gdevstc.c
@@ -362,6 +362,7 @@ stc_print_page(gx_device_printer * pdev, gp_file *prn_stream)
int prt_pixels; /* Number of pixels printed */
byte *col_line; /* A Line with a byte per pixel */
+ int code = 0;
#define OK4GO ((flags & STCOK4GO) != 0)
#define SORRY ( flags &= ~STCOK4GO)
@@ -591,7 +592,11 @@ stc_print_page(gx_device_printer * pdev, gp_file *prn_stream)
if(sd->stc.buf_y < sd->stc.prt_scans) { /* Test for White */
- gdev_prn_get_bits(pdev,sd->stc.buf_y,ext_line,&ext_data);
+ code = gdev_prn_get_bits(pdev,sd->stc.buf_y,ext_line,&ext_data);
+ if (code < 0) {
+ SORRY;
+ goto xit;
+ }
color = stc_iswhite(sd,prt_pixels,ext_data) ? ext_size : 0;
@@ -747,6 +752,7 @@ stc_print_page(gx_device_printer * pdev, gp_file *prn_stream)
*** Release the dynamic memory
***/
+xit:
if(ext_line != NULL)
gs_free(sd->memory, ext_line,ext_size,1,"stc_print_page/ext_line");
diff --git a/devices/gdevtfnx.c b/devices/gdevtfnx.c
index 578e964..d9593cd 100644
--- a/devices/gdevtfnx.c
+++ b/devices/gdevtfnx.c
@@ -126,13 +126,6 @@ tiff12_print_page(gx_device_printer * pdev, gp_file * file)
gx_device_tiff *const tfdev = (gx_device_tiff *)pdev;
int code;
- /* open the TIFF device */
- if (gdev_prn_file_is_new(pdev)) {
- tfdev->tif = tiff_from_filep(pdev, pdev->dname, file, tfdev->BigEndian, tfdev->UseBigTIFF);
- if (!tfdev->tif)
- return_error(gs_error_invalidfileaccess);
- }
-
code = gdev_tiff_begin_page(tfdev, file);
if (code < 0)
return code;
@@ -189,13 +182,6 @@ tiff_rgb_print_page(gx_device_printer * pdev, gp_file * file)
gx_device_tiff *const tfdev = (gx_device_tiff *)pdev;
int code;
- /* open the TIFF device */
- if (gdev_prn_file_is_new(pdev)) {
- tfdev->tif = tiff_from_filep(pdev, pdev->dname, file, tfdev->BigEndian, tfdev->UseBigTIFF);
- if (!tfdev->tif)
- return_error(gs_error_invalidfileaccess);
- }
-
code = gdev_tiff_begin_page(tfdev, file);
if (code < 0)
return code;
diff --git a/devices/gdevtifs.c b/devices/gdevtifs.c
index 2a52d3b..2d612ba 100644
--- a/devices/gdevtifs.c
+++ b/devices/gdevtifs.c
@@ -331,6 +331,9 @@ int gdev_tiff_begin_page(gx_device_tiff *tfdev,
profile_struct->device_profile[0], profile_struct->postren_profile,
&rendering_params);
}
+ if (tfdev->icclink == NULL) {
+ return_error(gs_error_VMerror);
+ }
/* If it is identity, release it now and set link to NULL */
if (tfdev->icclink->is_identity) {
tfdev->icclink->procs.free_link(tfdev->icclink);
@@ -477,7 +480,7 @@ tiff_print_page(gx_device_printer *dev, TIFF *tif, int min_feature_size)
for (row = 0; row < dev->height && code >= 0; row++) {
code = gdev_prn_copy_scan_lines(dev, row, data, size);
if (code < 0)
- break;
+ goto cleanup;
if (min_feature_size > 1) {
filtered_count = min_feature_size_process(data, min_feature_data);
if (filtered_count == 0)
diff --git a/devices/gdevtknk.c b/devices/gdevtknk.c
index cd88a42..35d98bf 100644
--- a/devices/gdevtknk.c
+++ b/devices/gdevtknk.c
@@ -125,6 +125,7 @@ tekink_print_page(gx_device_printer *pdev, gp_file *prn_stream)
register byte bdata,mdata,ydata,cdata;
register byte mask,inbyte;
register byte *indataend,*outdataend;
+ int code = 0;
/* Allocate a temporary buffer for color separation.
The buffer is partitioned into an input buffer and four
@@ -134,7 +135,8 @@ tekink_print_page(gx_device_printer *pdev, gp_file *prn_stream)
line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
color_line_size=(pdev->width+7)/8;
indata1=(byte *)malloc(line_size+4*(color_line_size+1));
- if (indata1==NULL) return -1;
+ if (indata1==NULL)
+ return_error(gs_error_VMerror);
/* pointers to the partions */
indataend=indata1+line_size;
bdata1=indataend;
@@ -150,7 +152,9 @@ tekink_print_page(gx_device_printer *pdev, gp_file *prn_stream)
scan_lines=pdev->height;
for (scan_line=0;scan_line<scan_lines;scan_line++){
/* get data */
- gdev_prn_copy_scan_lines(pdev,scan_line,indata1,line_size);
+ code = gdev_prn_copy_scan_lines(pdev,scan_line,indata1,line_size);
+ if (code < 0)
+ goto xit;
/* Separate data into color planes */
bdatap = bdata1+1;
mdatap = mdata1+1;
@@ -248,7 +252,8 @@ tekink_print_page(gx_device_printer *pdev, gp_file *prn_stream)
gp_fputs("\f",prn_stream);
}
+xit:
/* Deallocate temp buffer */
free(indata1);
- return 0;
+ return code;
}
diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index bb905b7..5b0429b 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -1796,6 +1796,9 @@ tiffsep_prn_open(gx_device * pdev)
profile_struct->device_profile[0], profile_struct->postren_profile,
&rendering_params);
}
+ if (pdev_sep->icclink == NULL) {
+ return_error(gs_error_VMerror);
+ }
/* If it is identity, release it now and set link to NULL */
if (pdev_sep->icclink->is_identity) {
pdev_sep->icclink->procs.free_link(pdev_sep->icclink);
diff --git a/devices/gdevwpr2.c b/devices/gdevwpr2.c
index 3f834b5..29af469 100644
--- a/devices/gdevwpr2.c
+++ b/devices/gdevwpr2.c
@@ -571,9 +571,12 @@ win_pr2_print_page(gx_device_printer * pdev, gp_file * file)
lines = scan_lines - y;
else
lines = yslice;
- for (i = 0; i < lines; i++)
- gdev_prn_copy_scan_lines(pdev, y + i,
+ for (i = 0; i < lines; i++) {
+ code = gdev_prn_copy_scan_lines(pdev, y + i,
row + (bmp_raster * (lines - 1 - i)), raster);
+ if (code < 0)
+ goto xit;
+ }
if (ratio > 1) {
StretchDIBits(wdev->hdcprn, 0, y*ratio, pdev->width*ratio, lines*ratio,
@@ -618,6 +621,7 @@ win_pr2_print_page(gx_device_printer * pdev, gp_file * file)
ShowWindow(wdev->hDlgModeless, SW_HIDE);
}
+xit:
GlobalUnlock(hrow);
GlobalFree(hrow);
diff --git a/devices/gdevxcf.c b/devices/gdevxcf.c
index 39c7283..a7e6617 100644
--- a/devices/gdevxcf.c
+++ b/devices/gdevxcf.c
@@ -1270,11 +1270,18 @@ xcf_write_image_data(xcf_write_ctx *xc, gx_device_printer *pdev)
tile_data = (byte **)gs_alloc_bytes(pdev->memory,
xc->n_tiles_x * sizeof(byte *),
"xcf_write_image_data");
+ if (line == NULL || tile_data == NULL) {
+ code = gs_error_VMerror;
+ goto xit;
+ }
+ memset(tile_data, 0, xc->n_tiles_x * sizeof(byte *));
for (tile_i = 0; tile_i < xc->n_tiles_x; tile_i++) {
int tile_bytes = xcf_tile_sizeof(xc, tile_i) * bytes_pp;
tile_data[tile_i] = gs_alloc_bytes(pdev->memory, tile_bytes,
"xcf_write_image_data");
+ if (tile_data[tile_i] == NULL)
+ goto xit;
}
for (tile_j = 0; tile_j < xc->n_tiles_y; tile_j++) {
int y0, y1;
@@ -1285,6 +1292,8 @@ xcf_write_image_data(xcf_write_ctx *xc, gx_device_printer *pdev)
y1 = min(xc->height, y0 + TILE_HEIGHT);
for (y = y0; y < y1; y++) {
code = gdev_prn_get_bits(pdev, y, line, &row);
+ if (code < 0)
+ goto xit;
if (link == NULL)
xcf_shuffle_to_tile(xc, tile_data, row, y);
else
@@ -1303,9 +1312,12 @@ xcf_write_image_data(xcf_write_ctx *xc, gx_device_printer *pdev)
}
}
- for (tile_i = 0; tile_i < xc->n_tiles_x; tile_i++) {
- gs_free_object(pdev->memory, tile_data[tile_i],
- "xcf_write_image_data");
+xit:
+ if (tile_data != NULL) {
+ for (tile_i = 0; tile_i < xc->n_tiles_x; tile_i++) {
+ gs_free_object(pdev->memory, tile_data[tile_i],
+ "xcf_write_image_data");
+ }
}
gs_free_object(pdev->memory, tile_data, "xcf_write_image_data");
gs_free_object(pdev->memory, line, "xcf_write_image_data");
diff --git a/devices/gdevxcmp.c b/devices/gdevxcmp.c
index 0aa7331..5cf5a56 100644
--- a/devices/gdevxcmp.c
+++ b/devices/gdevxcmp.c
@@ -134,13 +134,16 @@ alloc_std_cmap(gx_device_X *xdev, bool colored)
/* Allocate the dynamic color table, if needed and possible. */
/* Uses: vinfo, cman.num_rgb. Sets: cman.dynamic.*. */
-static void
+/* Return true if the allocation was successful. */
+static bool
alloc_dynamic_colors(gx_device_X * xdev, int num_colors)
{
if (num_colors > 0) {
xdev->cman.dynamic.colors = (x11_color_t **)
gs_malloc(xdev->memory, sizeof(x11_color_t *), xdev->cman.num_rgb,
"x11 cman.dynamic.colors");
+ if (xdev->cman.dynamic.colors == NULL)
+ return false;
if (xdev->cman.dynamic.colors) {
int i;
@@ -152,6 +155,7 @@ alloc_dynamic_colors(gx_device_X * xdev, int num_colors)
xdev->cman.dynamic.used = 0;
}
}
+ return true;
}
/* Allocate an X color, updating the reverse map. */
@@ -388,8 +392,9 @@ gdev_x_setup_colors(gx_device_X * xdev)
}
/* Allocate the dynamic color table. */
- alloc_dynamic_colors(xdev, CUBE(xdev->cman.num_rgb) -
- CUBE(xdev->color_info.dither_colors));
+ if (!alloc_dynamic_colors(xdev, CUBE(xdev->cman.num_rgb) -
+ CUBE(xdev->color_info.dither_colors)))
+ return_error(gs_error_VMerror);
#undef CUBE
#undef CBRT
break;
@@ -436,8 +441,9 @@ grayscale:
}
/* Allocate the dynamic color table. */
- alloc_dynamic_colors(xdev, xdev->cman.num_rgb -
- xdev->color_info.dither_grays);
+ if (!alloc_dynamic_colors(xdev, xdev->cman.num_rgb -
+ xdev->color_info.dither_grays))
+ return_error(gs_error_VMerror);
break;
case 'M':
monochrome:
diff --git a/devices/vector/gdevagl.h b/devices/vector/gdevagl.h
index e509f89..e356922 100644
--- a/devices/vector/gdevagl.h
+++ b/devices/vector/gdevagl.h
@@ -33,5 +33,5 @@ typedef struct treble_glyph_list_s {
typedef struct quad_glyph_list_s {
const char *Glyph;
- short Unicode[4];
+ unsigned short Unicode[4];
} quad_glyph_list_t;
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
index d918d60..b25a4a6 100644
--- a/devices/vector/gdevpdf.c
+++ b/devices/vector/gdevpdf.c
@@ -1020,6 +1020,7 @@ pdf_close_page(gx_device_pdf * pdev, int num_copies)
page->contents_id = pdev->contents_id;
page->NumCopies_set = pdev->NumCopies_set;
page->NumCopies = pdev->NumCopies;
+ page->UserUnit = pdev->UserUnit;
pdf_record_usage(pdev, pdev->contents_id, pdev->next_page);
pdf_record_usage(pdev, pdev->contents_length_id, pdev->next_page);
pdf_record_usage(pdev, page->Page->id, pdev->next_page);
@@ -1337,6 +1338,9 @@ pdf_write_page(gx_device_pdf *pdev, int page_num)
bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]);
}
pdf_print_orientation(pdev, page);
+ if (page->UserUnit != 1)
+ pprintg1(s, "/UserUnit %g\n", page->UserUnit);
+
pprintld1(s, "/Parent %ld 0 R\n", pdev->Pages->id);
if (pdev->ForOPDFRead && pdev->DoNumCopies && !pdev->ProduceDSC) {
if (page->NumCopies_set)
diff --git a/devices/vector/gdevpdfb.h b/devices/vector/gdevpdfb.h
index a47fec8..e1ca236 100644
--- a/devices/vector/gdevpdfb.h
+++ b/devices/vector/gdevpdfb.h
@@ -289,7 +289,8 @@ const gx_device_pdf PDF_DEVICE_IDENT =
-1, /* Last Form ID, start with -1 which means 'none' */
0, /* ExtensionMetadata */
0, /* PDFFormName */
- 0 /* PassThroughWriter */
+ 0, /* PassThroughWriter */
+ 1.0 /* UserUnit */
};
#else
diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c
index 877b7b1..1c54070 100644
--- a/devices/vector/gdevpdfe.c
+++ b/devices/vector/gdevpdfe.c
@@ -651,8 +651,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
{
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:pdf");
pdf_xml_attribute_value(s, "http://ns.adobe.com/pdf/1.3/");
@@ -689,8 +688,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
}
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:xmp");
pdf_xml_attribute_value(s, "http://ns.adobe.com/xap/1.0/");
pdf_xml_tag_end(s);
@@ -723,8 +721,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:xapMM");
pdf_xml_attribute_value(s, "http://ns.adobe.com/xap/1.0/mm/");
pdf_xml_attribute_name(s, "xapMM:DocumentID");
@@ -733,8 +730,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:dc");
pdf_xml_attribute_value(s, "http://purl.org/dc/elements/1.1/");
pdf_xml_attribute_name(s, "dc:format");
@@ -808,8 +804,7 @@ pdf_write_document_metadata(gx_device_pdf *pdev, const byte digest[6])
pdf_xml_newline(s);
if (pdev->PDFA != 0) {
pdf_xml_tag_open_beg(s, "rdf:Description");
- pdf_xml_attribute_name(s, "rdf:about");
- pdf_xml_attribute_value(s, instance_uuid);
+ pdf_xml_copy(s, " rdf:about=\"\"");
pdf_xml_attribute_name(s, "xmlns:pdfaid");
pdf_xml_attribute_value(s, "http://www.aiim.org/pdfa/ns/id/");
pdf_xml_attribute_name(s, "pdfaid:part");
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index fed96e4..2f9cea0 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1878,7 +1878,7 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
pdf_image_enum *pie = (pdf_image_enum *)info;
int height = pie->writer.height;
int data_height = height - pie->rows_left;
- int code = 0;
+ int code = 0, ecode;
if (pie->writer.pres)
((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
@@ -1920,6 +1920,12 @@ pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
if (pie->initial_colorspace != pdev->pcm_color_info_index)
pdf_set_process_color_model(pdev, pie->initial_colorspace);
+ /* Clean up any outstanding streams before freeing the enumerator */
+ while (pie->writer.alt_writer_count-- > 0) {
+ ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
+ if (ecode < 0 && code >= 0) code = ecode;
+ }
+
gx_image_free_enum(&info);
return code;
}
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
index df2ff37..2f29dba 100644
--- a/devices/vector/gdevpdfp.c
+++ b/devices/vector/gdevpdfp.c
@@ -127,6 +127,7 @@ static const gs_param_item_t pdf_param_items[] = {
pi("FastWebView", gs_param_type_bool, Linearise),
pi("NoOutputFonts", gs_param_type_bool, FlattenFonts),
pi("WantsPageLabels", gs_param_type_bool, WantsPageLabels),
+ pi("UserUnit", gs_param_type_float, UserUnit),
#undef pi
gs_param_item_end
};
@@ -237,6 +238,14 @@ gdev_pdf_get_param(gx_device *dev, char *Param, void *list)
if (strcmp(Param, "ForOPDFRead") == 0) {
return(param_write_bool(plist, "ForOPDFRead", &pdev->ForOPDFRead));
}
+ if (strcmp(Param, "PassUserUnit") == 0) {
+ bool dummy;
+ if (pdev->CompatibilityLevel > 1.5)
+ dummy = true;
+ else
+ dummy = false;
+ return(param_write_bool(plist, "PassUserUnit", &dummy));
+ }
if (!pdev->is_ps2write) {
if (strcmp(Param, "pdfmark") == 0){
return(param_write_null(plist, "pdfmark"));
@@ -559,6 +568,16 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
if (cl < 1.2) {
pdev->HaveCFF = false;
}
+
+ ecode = param_read_float(plist, "UserUnit", &pdev->UserUnit);
+ if (ecode < 0)
+ goto fail;
+ if (pdev->UserUnit == 0 || (pdev->UserUnit != 1 && pdev->CompatibilityLevel < 1.6)) {
+ ecode = gs_note_error(gs_error_rangecheck);
+ param_signal_error(plist, "UserUnit", ecode);
+ goto fail;
+ }
+
ecode = gdev_psdf_put_params(dev, plist);
if (ecode < 0)
goto fail;
diff --git a/devices/vector/gdevpdfx.h b/devices/vector/gdevpdfx.h
index f42d9f1..ad484ed 100644
--- a/devices/vector/gdevpdfx.h
+++ b/devices/vector/gdevpdfx.h
@@ -326,6 +326,7 @@ typedef struct pdf_page_s {
pdf_page_dsc_info_t dsc_info;
bool NumCopies_set; /* ps2write only. */
int NumCopies; /* ps2write only. */
+ float UserUnit; /* pdfwrite only */
} pdf_page_t;
#define private_st_pdf_page() /* in gdevpdf.c */\
gs_private_st_ptrs2(st_pdf_page, pdf_page_t, "pdf_page_t",\
@@ -901,6 +902,7 @@ struct gx_device_pdf_s {
* doing JPEG pass through we write the JPEG data here, and don't write
* anything in the image processing routines.
*/
+ float UserUnit;
};
#define is_in_page(pdev)\
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
index 5158418..7738321 100644
--- a/devices/vector/gdevtxtw.c
+++ b/devices/vector/gdevtxtw.c
@@ -2111,7 +2111,8 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!penum->text_state->Widths)
return gs_note_error(gs_error_VMerror);
- memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(penum->text_state->Widths, penum->Widths, penum->text.size * sizeof(float));
unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
@@ -2123,7 +2124,8 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
penum->TextBufferIndex, sizeof(float), "txtwrite alloc widths array");
if (!unsorted_entry->Widths)
return gs_note_error(gs_error_VMerror);
- memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
+ memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
+ memcpy(unsorted_entry->Widths, penum->Widths, penum->text.size * sizeof(float));
unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory,
(strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer");
diff --git a/doc/Language.htm b/doc/Language.htm
index 5f112a1..d8f9deb 100644
--- a/doc/Language.htm
+++ b/doc/Language.htm
@@ -463,6 +463,10 @@ Ghostscript's model generalizes that of PDF 1.4 in that Ghostscript
maintains separate alpha and mask values for opacity and shape, rather than
a single value with a Boolean that says whether it represents opacity or
shape.</p>
+<p>
+What follows is a subset of all the custom operators related to transparency, but
+covers the most useful, most common requirements.
+</p>
<h5><a name="Transparency_graphics_state_operators"></a>Graphics state
operators</h5>
@@ -495,23 +499,43 @@ the blending mode is <code>/Compatible</code>.</dd>
</dl>
<dl>
+<dt><code>- .currentblendmode <modename></code></dt>
+<dd>Returns the graphics state blend mode on the stack.
+</dl>
+
+<dl>
<dt><code><0..1> .setopacityalpha -</code></dt>
<dd>Sets the opacity alpha value in the graphics state.
The initial opacity alpha value is 1.</dd>
</dl>
<dl>
+<dt><code>- .currentopacityalpha <0..1></code></dt>
+<dd>Returns the graphics state opacity alpha on the stack.</dd>
+</dl>
+
+<dl>
<dt><code><0..1> .setshapealpha -</code></dt>
<dd>Sets the shape alpha value in the graphics state.
The initial shape alpha value is 1.</dd>
</dl>
<dl>
+<dt><code>- .currentshapealpha <0..1></code></dt>
+<dd>Returns the graphics state shape alpha on the stack.</dd>
+</dl>
+
+<dl>
<dt><code><bool> .settextknockout -</code></dt>
<dd>Sets the text knockout flag in the graphics state.
The initial value of the text knockout flag is <code>true</code>.</dd>
</dl>
+<dl>
+<dt><code>- .currenttextknockout <bool></code></dt>
+<dd>Returns the graphics state text knockout on the stack..</dd>
+</dl>
+
<h5><a name="Transparency_rendering_stack_operators"></a>Rendering stack
operators</h5>
diff --git a/gpdl/gpdl.mak b/gpdl/gpdl.mak
index 6a1bbc7..3864a92 100644
--- a/gpdl/gpdl.mak
+++ b/gpdl/gpdl.mak
@@ -17,6 +17,9 @@ GPDL_MAK=$(GPDLSRCDIR)$(D)gpdl.mak
GPDLSRC=$(GPDLSRCDIR)$(D)
GPDLPSISRC=$(GPDLSRCDIR)$(D)psi$(D)
+GPDLURFSRC=$(URFSRCDIR)$(D)
+GPDLIMGSRC=$(GPDLSRCDIR)$(D)image$(D)
+GPDLPWGSRC=$(GPDLSRCDIR)$(D)pwg$(D)
GPDLOBJ=$(GPDLOBJDIR)$(D)
GPDLGEN=$(GPDLGENDIR)$(D)
@@ -26,9 +29,18 @@ GLGEN=$(GLGENDIR)$(D)
GPDL_PSI_TOP_OBJ_FILE=psitop.$(OBJ)
GPDL_PSI_TOP_OBJ=$(GPDLOBJ)/$(GPDL_PSI_TOP_OBJ_FILE)
-GPDL_PSI_TOP_OBJS=$(GPDL_PSI_TOP_OBJ) $(GPDLOBJ)gpdlimpl.$(OBJ)
+GPDL_URF_TOP_OBJ_FILE=urftop.$(OBJ)
+
+GPDL_IMG_TOP_OBJ_FILE=imagetop.$(OBJ)
+GPDL_IMG_TOP_OBJ=$(GPDLOBJ)/$(GPDL_IMG_TOP_OBJ_FILE)
+
+GPDL_PWG_TOP_OBJ_FILE=pwgtop.$(OBJ)
+GPDL_PWG_TOP_OBJ=$(GPDLOBJ)/$(GPDL_PWG_TOP_OBJ_FILE)
+
+GPDL_PSI_TOP_OBJS=$(GPDL_PWG_TOP_OBJ) $(GPDL_IMG_TOP_OBJ) $(GPDL_URF_TOP_OBJ) $(GPDL_PSI_TOP_OBJ) $(GPDLOBJ)gpdlimpl.$(OBJ)
+
+LANG_CFLAGS=$(D_)PCL_INCLUDED$(_D) $(D_)PSI_INCLUDED$(_D) $(D_)XPS_INCLUDED$(_D) $(ENABLE_URF) $(D_)IMG_INCLUDED$(_D) $(D_)PWG_INCLUDED$(_D)
-LANG_CFLAGS=$(D_)PCL_INCLUDED$(_D) $(D_)PSI_INCLUDED$(_D) $(D_)XPS_INCLUDED$(_D)
GPDLCC=$(CC_) $(LANG_CFLAGS) $(I_)$(PSSRCDIR)$(_I) $(I_)$(PLSRCDIR)$(_I) $(I_)$(GLSRCDIR)$(_I) $(I_)$(DEVSRCDIR)$(_I) $(I_)$(GLGENDIR)$(_I) $(C_)
@@ -50,3 +62,21 @@ $(GPDL_PSI_TOP_OBJ): $(GPDLPSISRC)psitop.c $(AK) $(stdio__h)\
$(gsnogc_h) $(pltop_h) $(psitop_h) $(plparse_h) $(gsicc_manage_h)\
$(plfont_h) $(uconfig_h)
$(GPDLCC) $(GPDLPSISRC)psitop.c $(GPDLO_)$(GPDL_PSI_TOP_OBJ_FILE)
+
+# Note that we don't use $(GPDL_URF_TOP_OBJ) as the target of the
+# next make rule, as this expands to "" in builds that don't use
+# URF.
+$(GPDLOBJ)/$(GPDL_URF_TOP_OBJ_FILE): $(GPDLURFSRC)urftop.c $(AK)\
+ $(gxdevice_h) $(gserrors_h) $(gsstate_h) $(surfx_h) $(strimpl_h)\
+ $(gscoord_h) $(pltop_h)
+ $(GPDLCC) $(GPDLURFSRC)urftop.c $(GPDLO_)$(GPDL_URF_TOP_OBJ_FILE)
+
+$(GPDL_IMG_TOP_OBJ): $(GPDLIMGSRC)imagetop.c $(AK)\
+ $(gxdevice_h) $(gserrors_h) $(gsstate_h) $(strimpl_h) $(gscoord_h)\
+ $(jpeglib_h) $(setjmp__h) $(sjpeg_h) $(pltop_h)
+ $(GPDLCC) $(II)$(JI_)$(_I) $(GPDLIMGSRC)imagetop.c $(GPDLO_)$(GPDL_IMG_TOP_OBJ_FILE)
+
+$(GPDL_PWG_TOP_OBJ): $(GPDLPWGSRC)pwgtop.c $(AK)\
+ $(gxdevice_h) $(gserrors_h) $(gsstate_h) $(spwgx_h) $(strimpl_h)\
+ $(gscoord_h) $(pltop_h)
+ $(GPDLCC) $(II)$(JI_)$(_I) $(GPDLPWGSRC)pwgtop.c $(GPDLO_)$(GPDL_PWG_TOP_OBJ_FILE)
diff --git a/gpdl/image/imagetop.c b/gpdl/image/imagetop.c
new file mode 100644
index 0000000..b3232dc
--- /dev/null
+++ b/gpdl/image/imagetop.c
@@ -0,0 +1,855 @@
+/* Copyright (C) 2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* imagetop.c */
+/* Top-level API implementation of "Image" Language Interface */
+
+#include "pltop.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gsstate.h"
+#include "strimpl.h"
+#include "gscoord.h"
+#include "jpeglib.h"
+#include "setjmp_.h"
+#include "sjpeg.h"
+
+/* Forward decls */
+
+/************************************************************/
+/******** Language wrapper implementation (see pltop.h) *****/
+/************************************************************/
+
+typedef enum
+{
+ ii_state_identifying = 0,
+ ii_state_jpeg,
+ ii_state_jpeg_header,
+ ii_state_jpeg_start,
+ ii_state_jpeg_rows,
+ ii_state_jpeg_finish,
+ ii_state_flush
+} ii_state;
+
+typedef struct {
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+} img_error_mgr;
+
+/*
+ * Image interpreter instance
+ */
+typedef struct img_interp_instance_s {
+ gs_memory_t *memory;
+ gs_memory_t *cmemory;
+ gx_device *dev;
+ gx_device *nulldev;
+
+ gs_color_space *gray;
+ gs_color_space *rgb;
+ gs_color_space *cmyk;
+
+ /* Image parser state machine */
+ ii_state state;
+
+ int pages;
+
+ uint8_t bpp;
+ uint8_t cs;
+ uint32_t width;
+ uint32_t height;
+ uint32_t xresolution;
+ uint32_t yresolution;
+
+ uint32_t num_comps;
+ uint32_t byte_width;
+ uint32_t y;
+
+ uint32_t bytes_available_on_entry;
+
+ gs_image_t image;
+ gs_image_enum *penum;
+ gs_gstate *pgs;
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_source_mgr jsrc;
+ size_t bytes_to_skip;
+ img_error_mgr jerr;
+
+ byte *samples;
+
+} img_interp_instance_t;
+
+static int
+img_detect_language(const char *s, int len)
+{
+ const byte *hdr = (const byte *)s;
+ if (len >= 11) {
+ if (hdr[0] == 0xFF && hdr[1] == 0xd8 && hdr[2] == 0xff && hdr[3] == 0xe0 &&
+ strncmp("JFIF", s+6, 5) == 0)
+ return 100;
+ }
+ /* FIXME: Other formats go here */
+
+ return 0;
+}
+
+static const pl_interp_characteristics_t img_characteristics = {
+ "IMAGE",
+ img_detect_language,
+ "Artifex",
+ "0.01",
+ "11 Nov 2019",
+ 1 /* minimum input size */
+};
+
+/* GS's fakakta jpeg integration insists on putting a
+ * memory structure pointer in the decompress structs client data.
+ * This is no good to find our instance from. We therefore find
+ * it by offsetting back from the address of the cinfo. This is
+ * a nasty bit of casting, so wrap it in a macro. */
+#define IMG_FROM_CINFO(CINFO) \
+ (img_interp_instance_t *)(((char *)(CINFO))-offsetof(img_interp_instance_t,cinfo))
+
+
+/* Get implementation's characteristics */
+static const pl_interp_characteristics_t * /* always returns a descriptor */
+img_impl_characteristics(const pl_interp_implementation_t *impl) /* implementation of interpreter to alloc */
+{
+ return &img_characteristics;
+}
+
+static void
+img_deallocate(img_interp_instance_t *img)
+{
+ if (img == NULL)
+ return;
+
+ rc_decrement_cs(img->gray, "img_deallocate");
+ rc_decrement_cs(img->rgb, "img_deallocate");
+ rc_decrement_cs(img->cmyk, "img_deallocate");
+
+ if (img->pgs != NULL)
+ gs_gstate_free_chain(img->pgs);
+ gs_free_object(img->memory, img, "img_impl_allocate_interp_instance");
+}
+
+/* Deallocate a interpreter instance */
+static int
+img_impl_deallocate_interp_instance(pl_interp_implementation_t *impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ img_deallocate(img);
+ impl->interp_client_data = NULL;
+
+ return 0;
+}
+
+/* Do per-instance interpreter allocation/init. */
+static int
+img_impl_allocate_interp_instance(pl_interp_implementation_t *impl, gs_memory_t *mem)
+{
+ int code;
+ img_interp_instance_t *img
+ = (img_interp_instance_t *)gs_alloc_bytes(mem,
+ sizeof(img_interp_instance_t),
+ "img_impl_allocate_interp_instance");
+ if (!img)
+ return_error(gs_error_VMerror);
+ memset(img, 0, sizeof(*img));
+
+ img->memory = mem;
+ img->pgs = gs_gstate_alloc(mem);
+ if (img->pgs == NULL)
+ goto failVM;
+
+ /* Push one save level onto the stack to assuage the memory handling */
+ code = gs_gsave(img->pgs);
+ if (code < 0)
+ goto fail;
+
+ code = gsicc_init_iccmanager(img->pgs);
+ if (code < 0)
+ goto fail;
+
+ img->gray = gs_cspace_new_ICC(mem, img->pgs, 1);
+ img->rgb = gs_cspace_new_ICC(mem, img->pgs, 3);
+ img->cmyk = gs_cspace_new_ICC(mem, img->pgs, 4);
+
+ impl->interp_client_data = img;
+
+ return 0;
+
+failVM:
+ code = gs_note_error(gs_error_VMerror);
+fail:
+ (void)img_deallocate(img);
+ return code;
+}
+
+/*
+ * Get the allocator with which to allocate a device
+ */
+static gs_memory_t *
+img_impl_get_device_memory(pl_interp_implementation_t *impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ return img->dev ? img->dev->memory : NULL;
+}
+
+#if 0 /* UNUSED */
+static int
+img_impl_set_param(pl_interp_implementation_t *impl,
+ pl_set_param_type type,
+ const char *param,
+ const void *val)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ /* No params set here */
+ return 0;
+}
+
+static int
+img_impl_add_path(pl_interp_implementation_t *impl,
+ const char *path)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ /* No paths to add */
+ return 0;
+}
+
+static int
+img_impl_post_args_init(pl_interp_implementation_t *impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ /* No post args processing */
+ return 0;
+}
+#endif
+
+/* Prepare interp instance for the next "job" */
+static int
+img_impl_init_job(pl_interp_implementation_t *impl,
+ gx_device *device)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ img->dev = device;
+ img->state = ii_state_identifying;
+
+ return 0;
+}
+
+#if 0 /* UNUSED */
+static int
+img_impl_run_prefix_commands(pl_interp_implementation_t *impl,
+ const char *prefix)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+static int
+img_impl_process_file(pl_interp_implementation_t *impl, const char *filename)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+#endif
+
+/* Do any setup for parser per-cursor */
+static int /* ret 0 or +ve if ok, else -ve error code */
+img_impl_process_begin(pl_interp_implementation_t * impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+/* Ensure we have 'required' bytes to read, and further ensure
+ * that we have no UEL's within those bytes. */
+static int
+ensure_bytes(img_interp_instance_t *img, stream_cursor_read *pr, int required)
+{
+ int n;
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q;
+ int avail;
+
+ /* Find out how many bytes we need to check */
+ n = pr->limit - pr->ptr;
+ if (n > required)
+ n = required;
+
+ /* Make sure there are no UELs in that block */
+ q = p + n;
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL */
+ return avail < 9 ? gs_error_NeedInput : gs_error_InterpreterExit;
+ }
+ p++;
+ }
+
+ /* If we have enough bytes, great, if not, get some more */
+ return (n < required) ? gs_error_NeedInput : 0;
+}
+
+static int
+flush_to_uel(stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Bin everything to
+ * the start of the match. */
+ pr->ptr = p-1;
+ if (avail == 9) /* Complete match. Exit! */
+ return gs_error_InterpreterExit;
+ /* Partial match. Get more data. */
+ return gs_error_NeedInput;
+ }
+ p++;
+ }
+
+ pr->ptr = pr->limit;
+
+ return 0;
+}
+
+static int
+bytes_until_uel(const stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Everything up to
+ * the start of the match is up for grabs. */
+ return p - (pr->ptr+1);
+ }
+ p++;
+ }
+
+ return pr->limit - pr->ptr;
+}
+
+static int
+get32be(stream_cursor_read *pr)
+{
+ int v = pr->ptr[1] << 24;
+ v |= pr->ptr[2] << 16;
+ v |= pr->ptr[3] << 8;
+ v |= pr->ptr[4];
+ pr->ptr += 4;
+
+ return v;
+}
+
+static int
+get8(stream_cursor_read *pr)
+{
+ return *++(pr->ptr);
+}
+
+static void
+img_jpeg_init_source(j_decompress_ptr cinfo)
+{
+ /* We've already inited the source */
+}
+
+static boolean
+img_fill_input_buffer(j_decompress_ptr cinfo)
+{
+ return FALSE; /* We've filled the buffer already */
+}
+
+static void
+img_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+ img_interp_instance_t *img = IMG_FROM_CINFO(cinfo);
+ size_t n = cinfo->src->bytes_in_buffer;
+
+ if (n > num_bytes)
+ n = num_bytes;
+ img->jsrc.next_input_byte += num_bytes;
+ img->jsrc.bytes_in_buffer -= n;
+}
+
+static boolean
+img_resync_to_restart(j_decompress_ptr cinfo, int desired)
+{
+ return FALSE;
+}
+
+static void
+img_term_source(j_decompress_ptr cinfo)
+{
+}
+
+static void
+img_error_exit(j_common_ptr cinfo)
+{
+ img_error_mgr *jerr = (img_error_mgr *)cinfo->err;
+
+ longjmp(jerr->setjmp_buffer, 1);
+}
+
+static int
+fill_jpeg_source(img_interp_instance_t *img, stream_cursor_read * pr)
+{
+ size_t n = pr->limit - pr->ptr;
+ size_t skip = img->bytes_to_skip;
+
+ /* Skip any bytes we are supposed to be skipping. */
+ if (skip > 0) {
+ if (skip > n)
+ skip = n;
+ pr->ptr += skip;
+ n -= skip;
+ img->bytes_to_skip -= skip;
+ if (img->bytes_to_skip != 0)
+ return 1; /* Still more to skip */
+ }
+
+ /* Set up for the call into the jpeg lib */
+ img->jsrc.next_input_byte = pr->ptr+1;
+ img->jsrc.bytes_in_buffer = pr->limit - pr->ptr;
+ img->bytes_available_on_entry = img->jsrc.bytes_in_buffer;
+
+ return 0;
+}
+
+static int
+consume_jpeg_data(img_interp_instance_t *img, stream_cursor_read *pr)
+{
+ size_t bytes_read = img->jsrc.next_input_byte - (pr->ptr+1);
+ size_t n = pr->limit - pr->ptr;
+
+ if (n > bytes_read)
+ n = bytes_read;
+ pr->ptr += n;
+ bytes_read -= n;
+
+ /* We need to skip the next bytes_read bytes */
+ img->bytes_to_skip = bytes_read;
+
+ return (pr->limit - pr->ptr == img->bytes_available_on_entry);
+}
+
+static int
+img_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+ int need_more_data;
+
+ do
+ {
+ need_more_data = 0;
+ switch(img->state)
+ {
+ case ii_state_identifying:
+ {
+ const byte *hdr;
+ /* Try and get us 11 bytes */
+ code = ensure_bytes(img, pr, 11);
+ if (code < 0)
+ return code;
+ hdr = pr->ptr+1;
+ if (hdr[0] == 0xFF && hdr[1] == 0xd8 && hdr[2] == 0xff && hdr[3] == 0xe0 &&
+ memcmp("JFIF", hdr+6, 5) == 0)
+ {
+ img->state = ii_state_jpeg;
+ break;
+ }
+ img->state = ii_state_flush;
+ break;
+ }
+ case ii_state_jpeg:
+ code = gs_jpeg_mem_init(img->memory, (j_common_ptr)&img->cinfo);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+
+ img->cinfo.err = jpeg_std_error(&img->jerr.pub);
+ img->jerr.pub.error_exit = img_error_exit;
+ if (setjmp(img->jerr.setjmp_buffer)) {
+ img->state = ii_state_flush;
+ break;
+ }
+
+ jpeg_create_decompress(&img->cinfo);
+
+ img->cinfo.src = &img->jsrc;
+ img->jsrc.init_source = img_jpeg_init_source;
+ img->jsrc.fill_input_buffer = img_fill_input_buffer;
+ img->jsrc.skip_input_data = img_skip_input_data;
+ img->jsrc.resync_to_restart = img_resync_to_restart;
+ img->jsrc.term_source = img_term_source;
+
+ img->state = ii_state_jpeg_header;
+ break;
+ case ii_state_jpeg_header:
+ {
+ int ok;
+ gs_color_space *cs;
+ float scale, xext, yext, xoffset, yoffset;
+
+ if (fill_jpeg_source(img, pr)) {
+ need_more_data = 1;
+ break; /* No bytes left after skipping */
+ }
+ if (setjmp(img->jerr.setjmp_buffer)) {
+ jpeg_destroy_decompress(&img->cinfo);
+ img->state = ii_state_flush;
+ break;
+ }
+ ok = jpeg_read_header(&img->cinfo, TRUE);
+ need_more_data = consume_jpeg_data(img, pr);
+ if (ok == JPEG_SUSPENDED)
+ break;
+ need_more_data = 0;
+
+ img->width = img->cinfo.image_width;
+ img->height = img->cinfo.image_height;
+ img->num_comps = img->cinfo.num_components;
+ img->bpp = 8 * img->num_comps;
+ switch(img->num_comps) {
+ default:
+ case 1:
+ cs = img->gray;
+ img->cinfo.out_color_space = JCS_GRAYSCALE;
+ break;
+ case 3:
+ cs = img->rgb;
+ img->cinfo.out_color_space = JCS_RGB;
+ break;
+ case 4:
+ cs = img->cmyk;
+ img->cinfo.out_color_space = JCS_CMYK;
+ break;
+ }
+
+ /* Find us some X and Y resolutions */
+ img->xresolution = img->cinfo.X_density;
+ img->yresolution = img->cinfo.Y_density;
+ if (img->xresolution == 0)
+ img->xresolution = img->yresolution;
+ if (img->yresolution == 0)
+ img->yresolution = img->xresolution;
+ if (img->xresolution == 0)
+ img->xresolution = 72;
+ if (img->yresolution == 0)
+ img->yresolution = 72;
+
+ /* Scale to fit, if too large. */
+ scale = 1.0f;
+ if (img->width * 72 > img->dev->width * img->xresolution)
+ scale = ((float)img->dev->width * img->xresolution) / (img->width * 72);
+ if (scale * img->height * 72 > img->dev->height * img->yresolution)
+ scale = ((float)img->dev->height * img->yresolution) / (img->height * 72);
+
+ /* Centre */
+ xext = ((float)img->width * 72 * scale / img->xresolution);
+ xoffset = (img->dev->width - xext)/2;
+ yext = ((float)img->height * 72 * scale / img->yresolution);
+ yoffset = (img->dev->height - yext)/2;
+
+
+ /* Now we've got the data from the image header, we can
+ * make the gs image instance */
+ img->byte_width = (img->bpp>>3)*img->width;
+
+ img->nulldev = gs_currentdevice(img->pgs);
+ rc_increment(img->nulldev);
+ code = gs_setdevice_no_erase(img->pgs, img->dev);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+ gs_initmatrix(img->pgs);
+
+ code = gs_translate(img->pgs, xoffset, img->dev->height-yoffset);
+ if (code >= 0)
+ code = gs_scale(img->pgs, scale, -scale);
+ if (code >= 0)
+ code = gs_erasepage(img->pgs);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+
+ img->samples = gs_alloc_bytes(img->memory, img->byte_width, "img_impl_process(samples)");
+ if (img->samples == NULL) {
+ img->state = ii_state_flush;
+ break;
+ }
+
+ memset(&img->image, 0, sizeof(img->image));
+ gs_image_t_init(&img->image, cs);
+ img->image.BitsPerComponent = img->bpp/img->num_comps;
+ img->image.Width = img->width;
+ img->image.Height = img->height;
+
+ img->image.ImageMatrix.xx = img->xresolution / 72.0;
+ img->image.ImageMatrix.yy = img->yresolution / 72.0;
+
+ img->penum = gs_image_enum_alloc(img->memory, "img_impl_process(penum)");
+ if (img->penum == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ img->state = ii_state_flush;
+ return code;
+ }
+
+ code = gs_image_init(img->penum,
+ &img->image,
+ false,
+ false,
+ img->pgs);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ return code;
+ }
+
+ img->state = ii_state_jpeg_start;
+ break;
+ }
+ case ii_state_jpeg_start:
+ {
+ int ok;
+ if (fill_jpeg_source(img, pr)) {
+ need_more_data = 1;
+ break; /* No bytes left after skipping */
+ }
+ if (setjmp(img->jerr.setjmp_buffer)) {
+ jpeg_destroy_decompress(&img->cinfo);
+ img->state = ii_state_flush;
+ break;
+ }
+ ok = jpeg_start_decompress(&img->cinfo);
+ (void)consume_jpeg_data(img, pr);
+ if (ok == FALSE)
+ break;
+ img->state = ii_state_jpeg_rows;
+ break;
+ }
+ case ii_state_jpeg_rows:
+ {
+ int rows_decoded;
+ unsigned int used;
+
+ if (fill_jpeg_source(img, pr)) {
+ need_more_data = 1;
+ break; /* No bytes left after skipping */
+ }
+ if (setjmp(img->jerr.setjmp_buffer)) {
+ jpeg_destroy_decompress(&img->cinfo);
+ img->state = ii_state_flush;
+ break;
+ }
+ rows_decoded = jpeg_read_scanlines(&img->cinfo, &img->samples, 1);
+ need_more_data = consume_jpeg_data(img, pr);
+ if (rows_decoded == 0)
+ break; /* Not enough data for a scanline yet */
+ need_more_data = 0;
+
+ code = gs_image_next(img->penum, img->samples, img->byte_width, &used);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+ img->y++;
+ if (img->y == img->height) {
+ code = gs_image_cleanup_and_free_enum(img->penum, img->pgs);
+ img->penum = NULL;
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+ code = pl_finish_page(img->memory->gs_lib_ctx->top_of_system,
+ img->pgs, 1, true);
+ if (code < 0) {
+ img->state = ii_state_flush;
+ break;
+ }
+ img->state = ii_state_jpeg_finish;
+ }
+ break;
+ }
+ case ii_state_jpeg_finish:
+ {
+ int ok;
+
+ if (fill_jpeg_source(img, pr)) {
+ need_more_data = 1;
+ break; /* No bytes left after skipping */
+ }
+ if (setjmp(img->jerr.setjmp_buffer)) {
+ jpeg_destroy_decompress(&img->cinfo);
+ img->state = ii_state_flush;
+ break;
+ }
+ ok = jpeg_finish_decompress(&img->cinfo);
+ need_more_data = consume_jpeg_data(img, pr);
+ if (ok == FALSE)
+ break;
+ need_more_data = 0;
+ img->state = ii_state_flush;
+ break;
+ }
+ default:
+ case ii_state_flush:
+ if (setjmp(img->jerr.setjmp_buffer))
+ break;
+ jpeg_destroy_decompress(&img->cinfo);
+
+ gs_jpeg_mem_term((j_common_ptr)&img->cinfo);
+
+ if (img->penum) {
+ (void)gs_image_cleanup_and_free_enum(img->penum, img->pgs);
+ img->penum = NULL;
+ }
+
+ gs_free_object(img->memory, img->samples, "img_impl_process(samples)");
+ img->samples = NULL;
+ /* We want to bin any data we get up to, but not including
+ * a UEL. */
+ return flush_to_uel(pr);
+ }
+ } while (!need_more_data);
+
+ return code;
+}
+
+static int
+img_impl_process_end(pl_interp_implementation_t * impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+
+ /* FIXME: */
+ if (code == gs_error_InterpreterExit || code == gs_error_NeedInput)
+ code = 0;
+
+ return code;
+}
+
+/* Not implemented */
+static int
+img_impl_flush_to_eoj(pl_interp_implementation_t *impl, stream_cursor_read *cursor)
+{
+ const byte *p = cursor->ptr;
+ const byte *rlimit = cursor->limit;
+
+ /* Skip to, but leave UEL in buffer for PJL to find later */
+ for (; p < rlimit; ++p)
+ if (p[1] == '\033') {
+ uint avail = rlimit - p;
+
+ if (memcmp(p + 1, "\033%-12345X", min(avail, 9)))
+ continue;
+ if (avail < 9)
+ break;
+ cursor->ptr = p;
+ return 1; /* found eoj */
+ }
+ cursor->ptr = p;
+ return 0; /* need more */
+}
+
+/* Parser action for end-of-file */
+static int
+img_impl_process_eof(pl_interp_implementation_t *impl)
+{
+ return 0;
+}
+
+/* Report any errors after running a job */
+static int
+img_impl_report_errors(pl_interp_implementation_t *impl, /* interp instance to wrap up job in */
+ int code, /* prev termination status */
+ long file_position, /* file position of error, -1 if unknown */
+ bool force_to_cout /* force errors to cout */
+)
+{
+ return 0;
+}
+
+/* Wrap up interp instance after a "job" */
+static int
+img_impl_dnit_job(pl_interp_implementation_t *impl)
+{
+ img_interp_instance_t *img = (img_interp_instance_t *)impl->interp_client_data;
+
+ if (img->nulldev) {
+ int code = gs_setdevice(img->pgs, img->nulldev);
+ img->dev = NULL;
+ rc_decrement(img->nulldev, "img_impl_dnit_job(nulldevice)");
+ img->nulldev = NULL;
+ return code;
+ }
+ return 0;
+}
+
+/* Parser implementation descriptor */
+const pl_interp_implementation_t img_implementation = {
+ img_impl_characteristics,
+ img_impl_allocate_interp_instance,
+ img_impl_get_device_memory,
+ NULL, /* img_impl_set_param */
+ NULL, /* img_impl_add_path */
+ NULL, /* img_impl_post_args_init */
+ img_impl_init_job,
+ NULL, /* img_impl_run_prefix_commands */
+ NULL, /* img_impl_process_file */
+ img_impl_process_begin,
+ img_impl_process,
+ img_impl_process_end,
+ img_impl_flush_to_eoj,
+ img_impl_process_eof,
+ img_impl_report_errors,
+ img_impl_dnit_job,
+ img_impl_deallocate_interp_instance,
+ NULL
+};
diff --git a/gpdl/psi/gpdlpsi.mak b/gpdl/psi/gpdlpsi.mak
deleted file mode 100644
index 84bddb1..0000000
--- a/gpdl/psi/gpdlpsi.mak
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2001-2019 Artifex Software, Inc.
-# All Rights Reserved.
-#
-# This software is provided AS-IS with no warranty, either express or
-# implied.
-#
-# This software is distributed under license and may not be copied,
-# modified or distributed except as expressly authorized under the terms
-# of the license contained in the file LICENSE in this distribution.
-#
-# Refer to licensing information at http://www.artifex.com or contact
-# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
-# CA 94945, U.S.A., +1(415)492-9861, for further information.
-#
-
-# makefile for PS Interface (PSI) to Ghostscript PostScript.
-# Users of this makefile must define the following:
-# PSSRCDIR - the PS interpreter source directory
-# GLSRCDIR - the GS library source directory
-# GLGENDIR - the GS library generated file directory
-# PLSRCDIR - the PCL* support library source directory
-# PLOBJDIR - the PCL* support library object / executable directory
-# PSISRCDIR - the source directory
-# PSIGENDIR - the directory for source files generated during building
-# PSIOBJDIR - the object / executable directory
-# PSI_TOP_OBJ - object file to top-level interpreter API
-
-PLOBJ=$(PLOBJDIR)$(D)
-
-PSISRC=$(PSISRCDIR)$(D)
-PSIGEN=$(PSIGENDIR)$(D)
-PSIOBJ=$(PSIOBJDIR)$(D)
-PSIO_=$(O_)$(PSIOBJ)
-
-PSICCC=$(CC_) $(I_)$(PSISRCDIR)$(_I) $(I_)$(PSIGENDIR)$(_I) $(I_)$(PLSRCDIR)$(_I) $(I_)$(PSSRCDIR)$(_I) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLGENDIR)$(_I) $(C_)
-
-# Define the name of this makefile.
-PSI_MAK=$(PSISRC)psi.mak
-
-psi.clean: psi.config-clean psi.clean-not-config-clean
-
-psi.clean-not-config-clean: clean_gs
- $(RM_) $(PSIOBJ)*.$(OBJ)
- $(RM_) $(PSIOBJ)devs.tr6
-
-# devices are still created in the current directory. Until that
-# is fixed we will have to remove them from both directories.
-psi.config-clean:
- $(RM_) $(PSIOBJ)*.dev
- $(RM_) *.dev
-
-################ PS Language Interface ################
-
-# Top-level API
-$(PSI_TOP_OBJ): $(PSISRC)psitop.c $(AK) $(stdio__h)\
- $(string__h) $(gdebug_h) $(gp_h) $(gsdevice_h) $(gserrors_h) $(gsmemory_h)\
- $(gsstate_h) $(gsstruct_h) $(gspaint_h) $(gstypes_h) $(gxalloc_h) $(gxstate_h)\
- $(gsnogc_h) $(pltop_h) $(psitop_h) $(plparse_h) $(gsicc_manage_h)\
- $(PSIGEN)pconf.h $(plfont_h) $(uconfig_h) $(pconfig_h)
- $(PSICCC) $(PSISRC)psitop.c $(O_)$(PSI_TOP_OBJ)
-
-$(PSIOBJ)psi.dev: $(PSI_MAK) $(ECHOGS_XE) $(PLOBJ)pjl.dev
- $(SETMOD) $(PSIOBJ)psi $(PSI_TOP_OBJ)
- $(ADDMOD) $(PSIOBJ)psi -include $(PLOBJ)pl $(PLOBJ)pjl
diff --git a/gpdl/pwg/pwgtop.c b/gpdl/pwg/pwgtop.c
new file mode 100644
index 0000000..5e7549e
--- /dev/null
+++ b/gpdl/pwg/pwgtop.c
@@ -0,0 +1,718 @@
+/* Copyright (C) 2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+/* pwgtop.c */
+/* Top-level API implementation of "PWG" Language Interface */
+
+#include "pltop.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gsstate.h"
+#include "spwgx.h"
+#include "strimpl.h"
+#include "gscoord.h"
+
+/* Forward decls */
+
+/************************************************************/
+/******** Language wrapper implementation (see pltop.h) *****/
+/************************************************************/
+
+typedef enum
+{
+ ii_state_identifying = 0,
+ ii_state_pwg,
+ ii_state_pwg_header,
+ ii_state_pwg_data,
+ ii_state_flush
+} ii_state;
+
+/*
+ * PWG interpreter instance
+ */
+typedef struct pwg_interp_instance_s {
+ gs_memory_t *memory;
+ gx_device *dev;
+ gx_device *nulldev;
+
+ gs_color_space *gray;
+ gs_color_space *rgb;
+ gs_color_space *cmyk;
+
+ /* PWG parser state machine */
+ ii_state state;
+
+ int pages;
+
+ uint32_t bpc;
+ uint32_t bpp;
+ uint32_t bpl;
+ uint32_t colororder;
+ uint32_t cs;
+ uint32_t duplexMode;
+ uint32_t printQuality;
+ uint32_t mediaType;
+ uint32_t copies;
+ uint32_t width;
+ uint32_t height;
+ uint32_t xresolution;
+ uint32_t yresolution;
+
+ uint32_t num_comps;
+ uint32_t byte_width;
+ uint32_t x;
+ uint32_t y;
+
+ gs_image_t image;
+ gs_image_enum *penum;
+ gs_gstate *pgs;
+
+ stream_PWGD_state pwgd_state;
+ byte stream_buffer[2048];
+
+} pwg_interp_instance_t;
+
+static int
+pwg_detect_language(const char *s, int len)
+{
+ /* For postscript, we look for %! */
+ if (len >= 4) {
+ if (memcmp(s, "RaS2", 4) == 0)
+ return 100;
+ }
+
+ return 0;
+}
+
+static const pl_interp_characteristics_t pwg_characteristics = {
+ "PWG",
+ pwg_detect_language,
+ "Artifex",
+ "0.01",
+ "13 Nov 2019",
+ 1 /* minimum input size */
+};
+
+/* Get implementation's characteristics */
+static const pl_interp_characteristics_t * /* always returns a descriptor */
+pwg_impl_characteristics(const pl_interp_implementation_t *impl) /* implementation of interpreter to alloc */
+{
+ return &pwg_characteristics;
+}
+
+static void
+pwg_deallocate(pwg_interp_instance_t *pwg)
+{
+ if (pwg == NULL)
+ return;
+
+ rc_decrement_cs(pwg->gray, "pwg_deallocate");
+ rc_decrement_cs(pwg->rgb, "pwg_deallocate");
+ rc_decrement_cs(pwg->cmyk, "pwg_deallocate");
+
+ if (pwg->pgs != NULL)
+ gs_gstate_free_chain(pwg->pgs);
+ gs_free_object(pwg->memory, pwg, "pwg_impl_allocate_interp_instance");
+}
+
+/* Deallocate a interpreter instance */
+static int
+pwg_impl_deallocate_interp_instance(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ pwg_deallocate(pwg);
+ impl->interp_client_data = NULL;
+
+ return 0;
+}
+
+/* Do per-instance interpreter allocation/init. */
+static int
+pwg_impl_allocate_interp_instance(pl_interp_implementation_t *impl, gs_memory_t *mem)
+{
+ int code;
+ pwg_interp_instance_t *pwg
+ = (pwg_interp_instance_t *)gs_alloc_bytes(mem,
+ sizeof(pwg_interp_instance_t),
+ "pwg_impl_allocate_interp_instance");
+ if (!pwg)
+ return_error(gs_error_VMerror);
+ memset(pwg, 0, sizeof(*pwg));
+
+ pwg->memory = mem;
+ pwg->pgs = gs_gstate_alloc(mem);
+ if (pwg->pgs == NULL)
+ goto failVM;
+
+ /* Push one save level onto the stack to assuage the memory handling */
+ code = gs_gsave(pwg->pgs);
+ if (code < 0)
+ goto fail;
+
+ code = gsicc_init_iccmanager(pwg->pgs);
+ if (code < 0)
+ goto fail;
+
+ pwg->gray = gs_cspace_new_ICC(mem, pwg->pgs, 1);
+ pwg->rgb = gs_cspace_new_ICC(mem, pwg->pgs, 3);
+ pwg->cmyk = gs_cspace_new_ICC(mem, pwg->pgs, 4);
+
+ impl->interp_client_data = pwg;
+
+ return 0;
+
+failVM:
+ code = gs_note_error(gs_error_VMerror);
+fail:
+ (void)pwg_deallocate(pwg);
+ return code;
+}
+
+/*
+ * Get the allocator with which to allocate a device
+ */
+static gs_memory_t *
+pwg_impl_get_device_memory(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return pwg->dev ? pwg->dev->memory : NULL;
+}
+
+#if 0 /* UNUSED */
+static int
+pwg_impl_set_param(pl_interp_implementation_t *impl,
+ pl_set_param_type type,
+ const char *param,
+ const void *val)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No params set here */
+ return 0;
+}
+
+static int
+pwg_impl_add_path(pl_interp_implementation_t *impl,
+ const char *path)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No paths to add */
+ return 0;
+}
+
+static int
+pwg_impl_post_args_init(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ /* No post args processing */
+ return 0;
+}
+#endif
+
+/* Prepare interp instance for the next "job" */
+static int
+pwg_impl_init_job(pl_interp_implementation_t *impl,
+ gx_device *device)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ pwg->dev = device;
+ pwg->state = ii_state_identifying;
+
+ return 0;
+}
+
+#if 0 /* UNUSED */
+static int
+pwg_impl_run_prefix_commands(pl_interp_implementation_t *impl,
+ const char *prefix)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+static int
+pwg_impl_process_file(pl_interp_implementation_t *impl, const char *filename)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+#endif
+
+/* Do any setup for parser per-cursor */
+static int /* ret 0 or +ve if ok, else -ve error code */
+pwg_impl_process_begin(pl_interp_implementation_t * impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ return 0;
+}
+
+/* Ensure we have 'required' bytes to read, and further ensure
+ * that we have no UEL's within those bytes. */
+static int
+ensure_bytes(pwg_interp_instance_t *pwg, stream_cursor_read *pr, int required)
+{
+ int n;
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q;
+ int avail;
+
+ /* Find out how many bytes we need to check */
+ n = pr->limit - pr->ptr;
+ if (n > required)
+ n = required;
+
+ /* Make sure there are no UELs in that block */
+ q = p + n;
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL */
+ return avail < 9 ? gs_error_NeedInput : gs_error_InterpreterExit;
+ }
+ p++;
+ }
+
+ /* If we have enough bytes, great, if not, get some more */
+ return (n < required) ? gs_error_NeedInput : 0;
+}
+
+static int
+flush_to_uel(stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Bin everything to
+ * the start of the match. */
+ pr->ptr = p-1;
+ if (avail == 9) /* Complete match. Exit! */
+ return gs_error_InterpreterExit;
+ /* Partial match. Get more data. */
+ return gs_error_NeedInput;
+ }
+ p++;
+ }
+
+ pr->ptr = pr->limit;
+
+ return 0;
+}
+
+static int
+bytes_until_uel(const stream_cursor_read *pr)
+{
+ const uint8_t *p = pr->ptr+1;
+ const uint8_t *q = pr->limit+1;
+ int avail;
+
+ while (p != q) {
+ while (p != q && *p != '\033')
+ p++;
+ if (p == q)
+ break;
+ avail = pr->limit - pr->ptr;
+ if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
+ /* At least a partial match to a UEL. Everything up to
+ * the start of the match is up for grabs. */
+ return p - (pr->ptr+1);
+ }
+ p++;
+ }
+
+ return pr->limit - pr->ptr;
+}
+
+static int
+get32be(stream_cursor_read *pr)
+{
+ int v = pr->ptr[1] << 24;
+ v |= pr->ptr[2] << 16;
+ v |= pr->ptr[3] << 8;
+ v |= pr->ptr[4];
+ pr->ptr += 4;
+
+ return v;
+}
+
+static int
+get8(stream_cursor_read *pr)
+{
+ return *++(pr->ptr);
+}
+
+static int
+pwg_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+ gs_color_space *cs;
+
+ /* Loop while we have bytes to read */
+ while (pr->limit > pr->ptr)
+ {
+ switch(pwg->state)
+ {
+ case ii_state_identifying:
+ /* Try and get us 4 bytes for "RaS2" */
+ code = ensure_bytes(pwg, pr, 4);
+ if (code < 0)
+ return code;
+ if (memcmp("RaS2", (const char *)pr->ptr+1, 4) == 0)
+ {
+ pr->ptr += 4;
+ pwg->state = ii_state_pwg_header;
+ break;
+ }
+ pwg->state = ii_state_flush;
+ break;
+ case ii_state_pwg_header:
+ /* Try and get us 1796 bytes for the page header */
+ code = ensure_bytes(pwg, pr, 1796);
+ if (code < 0)
+ return code;
+ pr->ptr += 64; /* CString PwgRaster */
+ pr->ptr += 64; /* CString MediaColor */
+ pr->ptr += 64; /* CString MediaType */
+ pr->ptr += 64; /* CString PrintContentOptimize */
+ pr->ptr += 1-(256-267); /* Reserved */
+ (void)get32be(pr); /* WhenEnum CutMedia */
+ pwg->duplexMode = !!get32be(pr); /* Boolean Duplex */
+ pwg->xresolution = get32be(pr);
+ pwg->yresolution = get32be(pr);
+ pr->ptr += 1-(284-299); /* Reserved */
+ (void)!!get32be(pr); /* Boolean InsertSheet */
+ (void)get32be(pr); /* WhenEnum Jog */
+ (void)get32be(pr); /* EdgeEnum LeadingEdge FeedDirection */
+ pr->ptr += 1-(312-323); /* Reserved */
+ (void)get32be(pr); /* MediaPosition */
+ (void)get32be(pr); /* MediaWeightMetric */
+ pr->ptr += 1-(332-339); /* Reserved */
+ pwg->copies = get32be(pr); /* NumCopies */
+ if (pwg->copies == 0)
+ pwg->copies = 1;
+ (void)get32be(pr); /* OrientationEnum Orientation OrientationRequested */
+ pr->ptr += 1-(348-351); /* Reserved */
+ (void)get32be(pr); /* UnsignedInt PageSize */
+ (void)get32be(pr); /* UnsignedInt PageSize */
+ pr->ptr += 1-(360-367); /* Reserved */
+ (void)!!get32be(pr); /* Boolean Tumble */
+ pwg->width = get32be(pr); /* Width */
+ pwg->height = get32be(pr); /* Height */
+ pr->ptr += 1-(380-383); /* Reserved */
+ pwg->bpc = get32be(pr); /* Bits Per Color */
+ pwg->bpp = get32be(pr); /* Bits Per Pixel */
+ pwg->bpl = get32be(pr); /* Bytes Per Line */
+ pwg->colororder = get32be(pr); /* ColorOrderEnum ColorOrder */
+ pwg->cs = get32be(pr); /* ColorSpaceEnum ColorSpace */
+ pr->ptr += 1-(404-419); /* Reserved */
+ (void)get32be(pr); /* NumColors */
+ pr->ptr += 1-(424-451); /* Reserved */
+ (void)get32be(pr); /* TotalPageCount */
+ (void)get32be(pr); /* CrossFeedTransform */
+ (void)get32be(pr); /* FeedTransform */
+ (void)get32be(pr); /* ImageBoxLeft */
+ (void)get32be(pr); /* ImageBoxTop */
+ (void)get32be(pr); /* ImageBoxRight */
+ (void)get32be(pr); /* ImageBoxBottom */
+ (void)get32be(pr); /* SrgbColor AlternatePrimary */
+ pwg->printQuality = get32be(pr); /* PrintQuality */
+ pr->ptr += 1-(488-507); /* Reserved */
+ (void)get32be(pr); /* VendorIdentifier */
+ (void)get32be(pr); /* VendorLength */
+ pr->ptr += 1-(516-1603); /* VendorData */
+ pr->ptr += 1-(1604-1667); /* Reserved */
+ pr->ptr += 1-(1668-1731); /* RenderingIntent */
+ pr->ptr += 1-(1732-1795); /* PageSizeName */
+
+ /* Decode the header */
+ if (pwg->colororder != 0)
+ goto bad_header; /* 0 = chunky = only defined one so far */
+
+ switch(pwg->cs) {
+ case 3: /* DeviceBlack */
+ case 18: /* Sgray */
+ case 48: /* Device1 (Device color, 1 colorant) */
+ pwg->num_comps = 1;
+ cs = pwg->gray;
+ break;
+ case 1: /* DeviceRGB */
+ case 19: /* sRGB */
+ case 20: /* AdobeRGB */
+ pwg->num_comps = 3;
+ cs = pwg->rgb;
+ break;
+ case 6: /* DeviceCMYK */
+ pwg->num_comps = 4;
+ cs = pwg->cmyk;
+ break;
+ default:
+ goto bad_header;
+ }
+ if (pwg->bpc != 8)
+ goto bad_header;
+ if (pwg->bpp != 8*pwg->num_comps && pwg->bpp != 16*pwg->num_comps) {
+bad_header:
+ pwg->state = ii_state_flush;
+ break;
+ }
+ pwg->byte_width = (pwg->bpp>>3)*pwg->width;
+ if (pwg->bpl != pwg->byte_width)
+ goto bad_header;
+
+ pwg->nulldev = gs_currentdevice(pwg->pgs);
+ rc_increment(pwg->nulldev);
+ code = gs_setdevice_no_erase(pwg->pgs, pwg->dev);
+ if (code < 0)
+ goto early_flush;
+ gs_initmatrix(pwg->pgs);
+
+ code = gs_scale(pwg->pgs, 1.0, -1.0);
+ if (code >= 0)
+ code = gs_translate(pwg->pgs, 0.0, -pwg->dev->height);
+ if (code >= 0)
+ code = gs_erasepage(pwg->pgs);
+ if (code < 0)
+ goto early_flush;
+
+ memset(&pwg->image, 0, sizeof(pwg->image));
+ gs_image_t_init(&pwg->image, cs);
+ pwg->image.BitsPerComponent = pwg->bpp/pwg->num_comps;
+ pwg->image.Width = pwg->width;
+ pwg->image.Height = pwg->height;
+
+ pwg->image.ImageMatrix.xx = pwg->xresolution / 72.0;
+ pwg->image.ImageMatrix.yy = pwg->yresolution / 72.0;
+
+ pwg->penum = gs_image_enum_alloc(pwg->memory, "pwg_impl_process(penum)");
+ if (pwg->penum == NULL) {
+ code = gs_note_error(gs_error_VMerror);
+ goto early_flush;
+ }
+
+ code = gs_image_init(pwg->penum,
+ &pwg->image,
+ false,
+ false,
+ pwg->pgs);
+ if (code < 0)
+ goto early_flush;
+
+ s_init_state((stream_state *)&pwg->pwgd_state, &s_PWGD_template, pwg->memory);
+ if (s_PWGD_template.set_defaults)
+ s_PWGD_template.set_defaults((stream_state *)&pwg->pwgd_state);
+
+ pwg->pwgd_state.width = pwg->width;
+ pwg->pwgd_state.bpp = pwg->bpp;
+
+ code = (s_PWGD_template.init)((stream_state *)&pwg->pwgd_state);
+ if (code < 0)
+ goto early_flush;
+ pwg->x = pwg->y = 0;
+ pwg->state = ii_state_pwg_data;
+ break;
+ case ii_state_pwg_data:
+ {
+ int n = bytes_until_uel(pr);
+ stream_cursor_read local_r;
+ stream_cursor_write local_w;
+ int status;
+ unsigned int used;
+ int decoded_any = 0;
+
+ local_r.ptr = pr->ptr;
+ local_r.limit = local_r.ptr + n;
+
+ do {
+ local_w.ptr = pwg->stream_buffer-1;
+ local_w.limit = local_w.ptr + sizeof(pwg->stream_buffer);
+
+ status = (s_PWGD_template.process)((stream_state *)&pwg->pwgd_state,
+ &local_r, &local_w,
+ true);
+ /* status = 0 => need data
+ * 1 => need output space */
+ /* Copy the updated pointer back */
+ pr->ptr = local_r.ptr;
+ if (local_w.ptr + 1 == pwg->stream_buffer)
+ break; /* Failed to decode any data */
+ decoded_any = 1;
+
+ code = gs_image_next(pwg->penum, pwg->stream_buffer, local_w.ptr + 1 - pwg->stream_buffer, &used);
+ if (code < 0)
+ goto flush;
+
+ pwg->x += used;
+ while (pwg->x >= pwg->byte_width) {
+ pwg->x -= pwg->byte_width;
+ pwg->y++;
+ }
+ /* Loop while we haven't had all the lines, the decompression
+ * didn't ask for more data, and the decompression didn't give
+ * us more data. */
+ } while (pwg->y < pwg->height);
+
+ if (pwg->y == pwg->height) {
+ code = gs_image_cleanup_and_free_enum(pwg->penum, pwg->pgs);
+ pwg->penum = NULL;
+ if (code < 0)
+ goto flush;
+ code = pl_finish_page(pwg->memory->gs_lib_ctx->top_of_system,
+ pwg->pgs, pwg->copies, true);
+ if (code < 0)
+ goto flush;
+ if (pwg->pages > 0) {
+ pwg->pages--;
+ /* If we've reached the expected end, we should probably flush to UEL */
+ if (pwg->pages == 0)
+ pwg->state = ii_state_flush;
+ }
+ if (pwg->pwgd_state.templat->release)
+ pwg->pwgd_state.templat->release((stream_state *)&pwg->pwgd_state);
+ pwg->state = ii_state_pwg_header;
+ } else if (decoded_any == 0) {
+ /* Failed to make progress. Just give up to avoid livelocking. */
+ goto flush;
+ }
+ break;
+ }
+ default:
+ case ii_state_flush:
+ if (0) {
+flush:
+ if (pwg->pwgd_state.templat->release)
+ pwg->pwgd_state.templat->release((stream_state *)&pwg->pwgd_state);
+early_flush:
+ pwg->state = ii_state_flush;
+ }
+ /* We want to bin any data we get up to, but not including
+ * a UEL. */
+ return flush_to_uel(pr);
+ }
+ }
+
+ return code;
+}
+
+static int
+pwg_impl_process_end(pl_interp_implementation_t * impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+ int code = 0;
+
+ /* FIXME: */
+ if (code == gs_error_InterpreterExit || code == gs_error_NeedInput)
+ code = 0;
+
+ return code;
+}
+
+/* Not implemented */
+static int
+pwg_impl_flush_to_eoj(pl_interp_implementation_t *impl, stream_cursor_read *cursor)
+{
+ const byte *p = cursor->ptr;
+ const byte *rlimit = cursor->limit;
+
+ /* Skip to, but leave UEL in buffer for PJL to find later */
+ for (; p < rlimit; ++p)
+ if (p[1] == '\033') {
+ uint avail = rlimit - p;
+
+ if (memcmp(p + 1, "\033%-12345X", min(avail, 9)))
+ continue;
+ if (avail < 9)
+ break;
+ cursor->ptr = p;
+ return 1; /* found eoj */
+ }
+ cursor->ptr = p;
+ return 0; /* need more */
+}
+
+/* Parser action for end-of-file */
+static int
+pwg_impl_process_eof(pl_interp_implementation_t *impl)
+{
+ return 0;
+}
+
+/* Report any errors after running a job */
+static int
+pwg_impl_report_errors(pl_interp_implementation_t *impl, /* interp instance to wrap up job in */
+ int code, /* prev termination status */
+ long file_position, /* file position of error, -1 if unknown */
+ bool force_to_cout /* force errors to cout */
+)
+{
+ return 0;
+}
+
+/* Wrap up interp instance after a "job" */
+static int
+pwg_impl_dnit_job(pl_interp_implementation_t *impl)
+{
+ pwg_interp_instance_t *pwg = (pwg_interp_instance_t *)impl->interp_client_data;
+
+ if (pwg->nulldev) {
+ int code = gs_setdevice(pwg->pgs, pwg->nulldev);
+ pwg->dev = NULL;
+ rc_decrement(pwg->nulldev, "pwg_impl_dnit_job(nulldevice)");
+ pwg->nulldev = NULL;
+ return code;
+ }
+ return 0;
+}
+
+/* Parser implementation descriptor */
+const pl_interp_implementation_t pwg_implementation = {
+ pwg_impl_characteristics,
+ pwg_impl_allocate_interp_instance,
+ pwg_impl_get_device_memory,
+ NULL, /* pwg_impl_set_param */
+ NULL, /* pwg_impl_add_path */
+ NULL, /* pwg_impl_post_args_init */
+ pwg_impl_init_job,
+ NULL, /* pwg_impl_run_prefix_commands */
+ NULL, /* pwg_impl_process_file */
+ pwg_impl_process_begin,
+ pwg_impl_process,
+ pwg_impl_process_end,
+ pwg_impl_flush_to_eoj,
+ pwg_impl_process_eof,
+ pwg_impl_report_errors,
+ pwg_impl_dnit_job,
+ pwg_impl_deallocate_interp_instance,
+ NULL
+};
diff --git a/jbig2dec/jbig2.c b/jbig2dec/jbig2.c
index 97018ea..3d9f270 100644
--- a/jbig2dec/jbig2.c
+++ b/jbig2dec/jbig2.c
@@ -191,12 +191,14 @@ jbig2_get_uint16(const byte *bptr)
return get_uint16(bptr);
}
+/* coverity[ -tainted_data_return ] */
int32_t
jbig2_get_int32(const byte *bptr)
{
return ((int32_t) get_int16(bptr) << 16) | get_uint16(bptr + 2);
}
+/* coverity[ -tainted_data_return ] */
uint32_t
jbig2_get_uint32(const byte *bptr)
{
diff --git a/jbig2dec/jbig2_halftone.c b/jbig2dec/jbig2_halftone.c
index 69bd21e..e67c6d1 100644
--- a/jbig2dec/jbig2_halftone.c
+++ b/jbig2dec/jbig2_halftone.c
@@ -50,6 +50,12 @@ jbig2_hd_new(Jbig2Ctx *ctx, const Jbig2PatternDictParams *params, Jbig2Image *im
uint32_t i;
int j;
+ if (N == 0) {
+ /* We've wrapped. */
+ jbig2_error(ctx, JBIG2_SEVERITY_WARNING, -1, "params->GRAYMAX out of range");
+ return NULL;
+ }
+
/* allocate a new struct */
new = jbig2_new(ctx, Jbig2PatternDict, 1);
if (new != NULL) {
diff --git a/jpegxr/cw_emit.c b/jpegxr/cw_emit.c
index cda26fe..cefa11a 100644
--- a/jpegxr/cw_emit.c
+++ b/jpegxr/cw_emit.c
@@ -133,7 +133,7 @@ int jxrc_set_separate_alpha_image_plane(jxr_container_t cp, unsigned int alpha_p
static void emit_ifd(jxr_container_t cp)
{
- unsigned long ifd_mark;
+ unsigned long ifd_mark = 0;
int idx;
struct ifd_table ifd[64];
unsigned char buf[1024];
diff --git a/pcl/pcl/pcindxed.c b/pcl/pcl/pcindxed.c
index a174c7e..25637b7 100644
--- a/pcl/pcl/pcindxed.c
+++ b/pcl/pcl/pcindxed.c
@@ -208,8 +208,18 @@ unshare_indexed_cspace(pcl_cs_indexed_t ** ppindexed)
pindexed->palette.size);
memcpy(pnew->pen_widths, pindexed->pen_widths,
num_entries * sizeof(float));
- memcpy(pnew->norm, pindexed->norm, 3 * sizeof(pindexed->norm[0]));
- memcpy(pnew->Decode, pindexed->Decode, 6 * sizeof(float));
+
+ /* Coverity thinks next memcpy() might need to be memmove(), so we
+ explicitly check for the buffers being equal. */
+ if (pnew->norm != pindexed->norm) {
+ memcpy(pnew->norm, pindexed->norm, 3 * sizeof(pindexed->norm[0]));
+ }
+
+ /* Coverity thinks next memcpy() might need to be memmove(), so we
+ explicitly check for the buffers being equal. */
+ if (pnew->Decode != pindexed->Decode) {
+ memcpy(pnew->Decode, pindexed->Decode, 6 * sizeof(float));
+ }
return 0;
}
diff --git a/pcl/pcl/pcwhtidx.c b/pcl/pcl/pcwhtidx.c
index 0f3141c..00ada33 100644
--- a/pcl/pcl/pcwhtidx.c
+++ b/pcl/pcl/pcwhtidx.c
@@ -217,7 +217,8 @@ pcl_cmap_map_raster(const pcl_cs_indexed_t * pindexed,
/* allocate a new raster if necessary (pack scanlines) */
if (must_copy) {
- long nbytes = pin_pixinfo->size.x * pin_pixinfo->pix_depth;
+ /* Cast to long to avoid coverity warning about sign extension. */
+ long nbytes = (long) pin_pixinfo->size.x * pin_pixinfo->pix_depth;
nbytes = ((nbytes + 7) / 8);
pout_pixinfo->raster = nbytes;
diff --git a/pcl/pcl/pgdraw.c b/pcl/pcl/pgdraw.c
index 0a4baf3..9d17414 100644
--- a/pcl/pcl/pgdraw.c
+++ b/pcl/pcl/pgdraw.c
@@ -440,7 +440,7 @@ hpgl_set_graphics_line_attribute_state(hpgl_state_t * pgls,
* is not documented PCLTRM. Pen widths are maintained in
* plotter units
*/
- if (render_mode != hpgl_rm_character && pen_wid <= 14.0) {
+ if (pen_wid <= 14.0) {
hpgl_call(gs_setlinejoin(pgls->pgs, gs_join_none));
hpgl_call(gs_setlinecap(pgls->pgs, gs_cap_butt));
hpgl_call(gs_setlinewidth(pgls->pgs, pen_wid));
@@ -450,7 +450,6 @@ hpgl_set_graphics_line_attribute_state(hpgl_state_t * pgls,
switch (render_mode) {
- case hpgl_rm_character:
case hpgl_rm_polygon:
case hpgl_rm_clip_and_fill_polygon:
hpgl_call(gs_setlinejoin(pgls->pgs, gs_join_round));
diff --git a/pcl/pl/pjparse.c b/pcl/pl/pjparse.c
index 72c1be7..1060caf 100644
--- a/pcl/pl/pjparse.c
+++ b/pcl/pl/pjparse.c
@@ -731,8 +731,7 @@ pjl_search_for_file(pjl_parser_state_t * pst, char *pathname, char *filename,
struct stat stbuf;
/* should check length */
- strcpy(fontfilename, pathname);
- strcat(fontfilename, "/*");
+ snprintf(fontfilename, sizeof(fontfilename), "%s/*", pathname);
fe = gs_enumerate_files_init(pst->mem, fontfilename, strlen(fontfilename));
if (fe) {
do {
diff --git a/pcl/pl/plfont.c b/pcl/pl/plfont.c
index 514c105..9982701 100644
--- a/pcl/pl/plfont.c
+++ b/pcl/pl/plfont.c
@@ -406,7 +406,7 @@ pl_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
}
/* skip over the post header */
numGlyphs = u16(postp + 32);
- if (glyph < 0 || glyph > numGlyphs - 1) {
+ if (glyph > numGlyphs - 1) {
if_debug1m('=', pfont->memory,
"[=]glyph index %lx out of range\n", glyph);
return -1;
@@ -414,7 +414,7 @@ pl_glyph_name(gs_font * pfont, gs_glyph glyph, gs_const_string * pstr)
/* glyph name index starts at post + 34 each entry is 2 bytes */
glyph_name_index = u16(postp + 34 + (glyph * 2));
/* this shouldn't happen */
- if (glyph_name_index < 0 && glyph_name_index > 0x7fff)
+ if (glyph_name_index > 0x7fff)
return -1;
/* mac easy */
if (glyph_name_index < 258) {
diff --git a/pcl/pl/plimpl.c b/pcl/pl/plimpl.c
index 5fa03ae..2b5b0dd 100644
--- a/pcl/pl/plimpl.c
+++ b/pcl/pl/plimpl.c
@@ -37,6 +37,12 @@ extern pl_interp_implementation_t svg_implementation;
extern pl_interp_implementation_t ps_implementation;
+extern pl_interp_implementation_t urf_implementation;
+
+extern pl_interp_implementation_t img_implementation;
+
+extern pl_interp_implementation_t pwg_implementation;
+
/* Zero-terminated list of pointers to implementations */
pl_interp_implementation_t *pdl_implementations[] = {
&pjl_implementation,
@@ -53,6 +59,15 @@ pl_interp_implementation_t *pdl_implementations[] = {
#ifdef PDF_INCLUDED
&pdf_implementation,
#endif
+#ifdef URF_INCLUDED
+ &urf_implementation,
+#endif
+#ifdef IMG_INCLUDED
+ &img_implementation,
+#endif
+#ifdef PWG_INCLUDED
+ &pwg_implementation,
+#endif
0
};
@@ -66,4 +81,3 @@ const gs_ptr_procs_t ptr_string_procs = { NULL, NULL, NULL };
const gs_ptr_procs_t ptr_const_string_procs = { NULL, NULL, NULL };
const gs_ptr_procs_t ptr_name_index_procs = { NULL, NULL, NULL };
#endif
-
diff --git a/pcl/pl/pllfont.c b/pcl/pl/pllfont.c
index f0b9f19..4bf49d6 100644
--- a/pcl/pl/pllfont.c
+++ b/pcl/pl/pllfont.c
@@ -255,7 +255,7 @@ pl_fill_in_mt_font(gs_font_base * pfont, pl_font_t * plfont, ushort handle,
pfont->FontBBox.p.x = pfont->FontBBox.p.y =
pfont->FontBBox.q.x = pfont->FontBBox.q.y = 0;
- uid_set_UniqueID(&pfont->UID, unique_id | (handle << 16));
+ uid_set_UniqueID(&pfont->UID, unique_id | ( ((long) handle) << 16));
pfont->encoding_index = 1; /****** WRONG ******/
pfont->nearest_encoding_index = 1; /****** WRONG ******/
}
@@ -308,7 +308,7 @@ pl_load_ufst_lineprinter(gs_memory_t * mem, pl_dict_t * pfontdict,
if (use_unicode_names_for_keys)
code = pl_dict_put(pfontdict,
(const byte *)resident_table[i].unicode_fontname,
- 32, pplfont);
+ sizeof(resident_table[i].unicode_fontname), pplfont);
else {
byte key[3];
@@ -540,8 +540,9 @@ pl_load_built_in_mtype_fonts(const char *pathname, gs_memory_t * mem,
}
if (use_unicode_names_for_keys)
code = pl_dict_put(pfontdict,
- (const byte *)resident_table[j].
- unicode_fontname, 32, plfont);
+ (const byte *)resident_table[j].unicode_fontname,
+ sizeof(resident_table[j].unicode_fontname),
+ plfont);
else {
key[2] = (byte) j;
key[0] = key[1] = 0;
@@ -702,7 +703,8 @@ pl_load_built_in_fonts(const char *pathname, gs_memory_t * mem,
residentp->character_complement, 8);
if (use_unicode_names_for_keys)
code = pl_dict_put(pfontdict,
- (const byte *)residentp->unicode_fontname, 32,
+ (const byte *)residentp->unicode_fontname,
+ sizeof(residentp->unicode_fontname),
plfont);
else {
key[2] = (byte) (residentp - resident_table);
diff --git a/psi/dscparse.c b/psi/dscparse.c
index e754a82..0c34eb1 100644
--- a/psi/dscparse.c
+++ b/psi/dscparse.c
@@ -3822,7 +3822,7 @@ dsc_dcs2_fixup(CDSC *dsc)
DSC_OFFSET *pbegin;
DSC_OFFSET *pend;
DSC_OFFSET end;
- CDCS2 *pdcs = dsc->dcs2;
+ CDCS2 *pdcs = NULL;
/* Now treat the initial EPS file as a single page without
* headers or trailer, so page extraction will fetch the
* the correct separation. */
@@ -3888,6 +3888,14 @@ dsc_dcs2_fixup(CDSC *dsc)
*pbegin = *pend;
end = 0; /* end of composite is start of first separation */
+ /* we used to do this where the pointer is declared, but Coverity points out
+ * that dsc_alloc_string can call dsc_reset which can free dsc and dsc->dcs2.
+ * By deferring the initialisation to here we can ensure we don't have a
+ * dangling pointer. This makes me suspiciouos that DCS (not DSC!) comments
+ * have never worked properly.
+ */
+ pdcs = dsc->dcs2;
+
while (pdcs) {
page_number = dsc->page_count;
if ((pdcs->begin) && (pdcs->colourname != NULL)) {
diff --git a/psi/imainarg.c b/psi/imainarg.c
index 76653f3..c5d74ca 100644
--- a/psi/imainarg.c
+++ b/psi/imainarg.c
@@ -509,7 +509,9 @@ run_stdin:
break;
}
if (code >= 0)
- code = runarg(minst, "]put", psarg, ".runfile", runInit | runFlush, minst->user_errors, NULL, NULL);
+ code = run_string(minst, "]put", 0, minst->user_errors, NULL, NULL);
+ if (code >= 0)
+ code = argproc(minst, psarg);
arg_free((char *)psarg, minst->heap);
if (code >= 0)
code = gs_error_Quit;
diff --git a/psi/int.mak b/psi/int.mak
index d34c2e7..f339ccf 100644
--- a/psi/int.mak
+++ b/psi/int.mak
@@ -358,7 +358,7 @@ $(PSOBJ)zfilter.$(OBJ) : $(PSSRC)zfilter.c $(OP) $(memory__h)\
$(files_h) $(ialloc_h) $(idict_h) $(idparam_h) $(ifilter_h) $(ilevel_h)\
$(sfilter_h) $(srlx_h) $(sstring_h) $(stream_h) $(strimpl_h)\
$(INT_MAK) $(MAKEDIRS)
- $(PSCC) $(PSO_)zfilter.$(OBJ) $(C_) $(PSSRC)zfilter.c
+ $(PSCC) $(ENABLE_URF) $(URF_INCLUDE) $(PSO_)zfilter.$(OBJ) $(C_) $(PSSRC)zfilter.c
$(PSOBJ)zfproc.$(OBJ) : $(PSSRC)zfproc.c $(GH) $(memory__h) $(stat__h)\
$(oper_h)\
diff --git a/psi/msvc.mak b/psi/msvc.mak
index c811b7b..61e7dfa 100644
--- a/psi/msvc.mak
+++ b/psi/msvc.mak
@@ -244,6 +244,26 @@ GPDLGENDIR=$(GLGENDIR)
GPDLOBJDIR=$(GLOBJDIR)
!endif
+!ifndef URFSRCDIR
+URFSRCDIR=.\urf
+!endif
+!ifndef URFGENDIR
+URFGENDIR=$(GLGENDIR)
+!endif
+!ifndef URFOBJDIR
+URFOBJDIR=$(GLOBJDIR)
+!endif
+
+!ifndef IMGSRCDIR
+IMGSRCDIR=.\gpdl\img
+!endif
+!ifndef IMGGENDIR
+IMGGENDIR=$(GLGENDIR)
+!endif
+!ifndef IMGOBJDIR
+IMGOBJDIR=$(GLOBJDIR)
+!endif
+
CONTRIBDIR=.\contrib
# Can we build PCL and XPS and PDF
@@ -594,6 +614,28 @@ WITH_CUPS=0
WITH_CUPS=0
!endif
+# Should we build URF...
+!ifdef WITH_URF
+!if "$(WITH_URF)"!="0"
+WITH_URF=1
+!else
+WITH_URF=0
+!endif
+!else
+!if exist ("$(URFSRCDIR)")
+WITH_URF=1
+!else
+WITH_URF=0
+!endif
+!endif
+!if "$(WITH_URF)"=="1"
+ENABLE_URF=$(D_)URF_INCLUDED$(_D)
+GPDL_URF_TOP_OBJ=$(GPDLOBJ)/$(GPDL_URF_TOP_OBJ_FILE)
+URF_INCLUDE=$(I_)$(URFSRCDIR)$(_I)
+URF_DEV=$(GLD)urfd.dev
+SURFX_H=$(URFSRCDIR)$(D)surfx.h
+!endif
+
# Should we build using CAL....
CALSRCDIR=cal
!ifdef WITH_CAL
@@ -1473,7 +1515,7 @@ FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev
$(GLD)seprlib.dev $(GLD)translib.dev $(GLD)cidlib.dev $(GLD)psf0lib.dev $(GLD)psf1lib.dev\
$(GLD)psf2lib.dev $(GLD)lzwd.dev $(GLD)sicclib.dev $(GLD)mshandle.dev $(GLD)mspoll.dev \
$(GLD)ramfs.dev $(GLD)sjpx.dev $(GLD)sjbig2.dev \
- $(GLD)pwgd.dev $(GLD)siscale.dev
+ $(GLD)pwgd.dev $(GLD)siscale.dev $(URF_DEV)
!ifndef METRO
@@ -1536,6 +1578,9 @@ DEVICE_DEVS16=$(DD)bbox.dev $(DD)plib.dev $(DD)plibg.dev $(DD)plibm.dev $(DD)pli
!if "$(WITH_CUPS)" == "1"
DEVICE_DEVS16=$(DEVICE_DEVS16) $(DD)cups.dev
!endif
+!if "$(WITH_URF)" == "1"
+DEVICE_DEVS16=$(DEVICE_DEVS16) $(DD)urfgray.dev $(DD)urfrgb.dev $(DD)urfcmyk.dev
+!endif
# Overflow for DEVS3,4,5,6,9
DEVICE_DEVS17=$(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev
DEVICE_DEVS18=$(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev $(DD)jetp3852.dev $(DD)r4081.dev
diff --git a/psi/zfilter.c b/psi/zfilter.c
index dd06c75..dfe3a1d 100644
--- a/psi/zfilter.c
+++ b/psi/zfilter.c
@@ -32,6 +32,10 @@
#include "ifilter.h"
#include "files.h" /* for filter_open, file_d'_buffer_size */
+#ifdef URF_INCLUDED
+#include "urffilter.c"
+#endif
+
/* <source> ASCIIHexEncode/filter <file> */
/* <source> <dict> ASCIIHexEncode/filter <file> */
static int
@@ -497,6 +501,9 @@ const op_def zfilter_op_defs[] = {
{"2RunLengthEncode", zRLE},
{"1RunLengthDecode", zRLD},
{"1PWGDecode", zPWGD},
+#ifdef URF_INCLUDED
+ {"1URFDecode", zURFD},
+#endif
{"3SubFileDecode", zSFD},
{"1.EOFDecode", zEOFD},
op_def_end(0)
diff --git a/windows/ghostpdl.vcproj b/windows/ghostpdl.vcproj
index bfddbd2..c105cc3 100644
--- a/windows/ghostpdl.vcproj
+++ b/windows/ghostpdl.vcproj
@@ -310,6 +310,30 @@
>
</File>
</Filter>
+ <Filter
+ Name="urf"
+ >
+ <File
+ RelativePath="..\gpdl\urf\urftop.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="image"
+ >
+ <File
+ RelativePath="..\gpdl\image\imagetop.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="pwg"
+ >
+ <File
+ RelativePath="..\gpdl\pwg\pwgtop.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
diff --git a/windows/ghostscript.vcproj b/windows/ghostscript.vcproj
index b7cc9d5..c06c7b1 100644
--- a/windows/ghostscript.vcproj
+++ b/windows/ghostscript.vcproj
@@ -9628,6 +9628,26 @@
>
</File>
</Filter>
+ <Filter
+ Name="urf"
+ >
+ <File
+ RelativePath="..\urf\gdevurf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\urf\surfd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\urf\surfx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\urf\urffilter.c"
+ >
+ </File>
+ </Filter>
</Files>
<Globals>
</Globals>
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index 94a8f5f..e08a068 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -264,6 +264,7 @@ xps_paint_image_brush_imp(xps_context_t *ctx, xps_image_t *image, int alpha)
gsimage.Interpolate = 1;
+ /* FIXME: leak enum in case of error */
penum = gs_image_enum_alloc(ctx->memory, "xps_parse_image_brush (gs_image_enum_alloc)");
if (!penum)
return gs_throw(gs_error_VMerror, "gs_enum_allocate failed");
diff --git a/xps/xpsjxr.c b/xps/xpsjxr.c
index 89eaf19..e12bbee 100644
--- a/xps/xpsjxr.c
+++ b/xps/xpsjxr.c
@@ -203,7 +203,11 @@ xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *output)
xps_free(ctx, name);
return gs_throw(gs_error_invalidfileaccess, "cannot write to scratch file");
}
- xps_fseek(file, 0, SEEK_SET);
+ rc = xps_fseek(file, 0, SEEK_SET);
+ if (rc != 0) {
+ xps_free(ctx, name);
+ return gs_throw(gs_error_invalidfileaccess, "cannot write to scratch file");
+ }
container = jxr_create_container();
rc = jxr_read_image_container(container, gp_get_file(file));
@@ -236,11 +240,19 @@ xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *output)
state.output = output;
jxr_set_user_data(image, &state);
- xps_fseek(file, offset, SEEK_SET);
+ rc = xps_fseek(file, offset, SEEK_SET);
+ if (rc != 0) {
+ xps_free(ctx, name);
+ jxr_destroy_container(container);
+ jxr_destroy(image);
+ return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
+ }
+
rc = jxr_read_image_bitstream(image, gp_get_file(file));
if (rc < 0) {
xps_free(ctx, name);
jxr_destroy_container(container);
+ jxr_destroy(image);
return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
}
@@ -265,11 +277,19 @@ xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *output)
state.output = output;
jxr_set_user_data(image, &state);
- xps_fseek(file, alpha_offset, SEEK_SET);
+ rc = xps_fseek(file, alpha_offset, SEEK_SET);
+ if (rc != 0) {
+ xps_free(ctx, name);
+ jxr_destroy_container(container);
+ jxr_destroy(image);
+ return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
+ }
+
rc = jxr_read_image_bitstream(image, gp_get_file(file));
if (rc < 0) {
xps_free(ctx, name);
jxr_destroy_container(container);
+ jxr_destroy(image);
return gs_throw1(-1, "jxr_read_image_bitstream: %s", jxr_error_string(rc));
}
diff --git a/xps/xpstop.c b/xps/xpstop.c
index 49d31c7..a53cc7a 100644
--- a/xps/xpstop.c
+++ b/xps/xpstop.c
@@ -127,6 +127,7 @@ xps_impl_allocate_interp_instance(pl_interp_implementation_t *impl,
return gs_error_VMerror;
}
+ /* FIXME: check return value */
gsicc_init_iccmanager(pgs);
memset(ctx, 0, sizeof(xps_context_t));
Summary of changes:
Makefile.in | 16 +-
Resource/Init/gs_cidfm.ps | 7 +-
Resource/Init/gs_lev2.ps | 2 +-
Resource/Init/gs_res.ps | 2 +-
Resource/Init/pdf_draw.ps | 11 +-
Resource/Init/pdf_font.ps | 387 +++++++++++---------
Resource/Init/pdf_main.ps | 40 ++-
Resource/Init/pdf_ops.ps | 48 ++-
base/gdevdevn.c | 4 +-
base/gdevdflt.c | 3 +-
base/gdevvec.c | 5 +
base/gpmisc.c | 6 +-
base/gsicc_create.c | 6 +-
base/gxclrast.c | 1 +
base/gxhintn.c | 5 +-
base/gxiscale.c | 1 +
base/lib.mak | 11 +
base/spwgd.c | 11 +-
base/unix-gcc.mak | 2 +-
configure.ac | 57 ++-
contrib/contrib.mak | 24 ++
contrib/gdevadmp.c | 410 +++++++++++++++++++++
contrib/gdevdj9.c | 2 +-
contrib/gdevlx32.c | 17 +-
contrib/gdevlx7.c | 13 +-
contrib/gdevmd2k.c | 6 +-
contrib/japanese/gdev10v.c | 3 +-
contrib/japanese/gdevlbp3.c | 4 +-
devices/devs.mak | 19 +
devices/gdev3852.c | 7 +-
devices/gdev4081.c | 23 +-
devices/gdev4693.c | 29 +-
devices/gdev8510.c | 8 +-
devices/gdevatx.c | 4 +-
devices/gdevbit.c | 12 +-
devices/gdevbj10.c | 3 +-
devices/gdevbmp.c | 4 +-
devices/gdevccr.c | 8 +-
devices/gdevcdj.c | 8 +-
devices/gdevcfax.c | 4 +-
devices/gdevcif.c | 13 +-
devices/gdevclj.c | 8 +-
devices/gdevcljc.c | 2 +-
devices/gdevdjtc.c | 12 +-
devices/gdevdm24.c | 38 +-
devices/gdevepsc.c | 18 +-
devices/gdevepsn.c | 58 ++-
devices/gdevescp.c | 35 +-
devices/gdevgprf.c | 2 +
devices/gdevhl7x.c | 43 ++-
devices/gdevicov.c | 20 +-
devices/gdevifno.c | 11 +-
devices/gdevimgn.c | 12 +-
devices/gdevjbig2.c | 6 +-
devices/gdevjpx.c | 4 +-
devices/gdevl31s.c | 10 +-
devices/gdevlbp8.c | 10 +-
devices/gdevlj56.c | 3 +-
devices/gdevlp8k.c | 38 +-
devices/gdevlxm.c | 30 +-
devices/gdevmgr.c | 16 +-
devices/gdevn533.c | 11 +-
devices/gdevokii.c | 23 +-
devices/gdevpbm.c | 2 +
devices/gdevpdfimg.c | 18 +-
devices/gdevperm.c | 10 +-
devices/gdevphex.c | 33 +-
devices/gdevpjet.c | 14 +-
devices/gdevpsim.c | 18 +-
devices/gdevrinkj.c | 25 +-
devices/gdevsppr.c | 13 +-
devices/gdevstc.c | 8 +-
devices/gdevtfnx.c | 14 -
devices/gdevtifs.c | 5 +-
devices/gdevtknk.c | 11 +-
devices/gdevtsep.c | 3 +
devices/gdevwpr2.c | 8 +-
devices/gdevxcf.c | 18 +-
devices/gdevxcmp.c | 16 +-
devices/vector/gdevagl.h | 2 +-
devices/vector/gdevpdf.c | 4 +
devices/vector/gdevpdfb.h | 3 +-
devices/vector/gdevpdfe.c | 15 +-
devices/vector/gdevpdfi.c | 8 +-
devices/vector/gdevpdfp.c | 19 +
devices/vector/gdevpdfx.h | 2 +
devices/vector/gdevtxtw.c | 6 +-
doc/Language.htm | 24 ++
gpdl/gpdl.mak | 34 +-
gpdl/image/imagetop.c | 855 ++++++++++++++++++++++++++++++++++++++++++++
gpdl/psi/gpdlpsi.mak | 64 ----
gpdl/pwg/pwgtop.c | 718 +++++++++++++++++++++++++++++++++++++
jbig2dec/jbig2.c | 2 +
jbig2dec/jbig2_halftone.c | 6 +
jpegxr/cw_emit.c | 2 +-
pcl/pcl/pcindxed.c | 14 +-
pcl/pcl/pcwhtidx.c | 3 +-
pcl/pcl/pgdraw.c | 3 +-
pcl/pl/pjparse.c | 3 +-
pcl/pl/plfont.c | 4 +-
pcl/pl/plimpl.c | 16 +-
pcl/pl/pllfont.c | 12 +-
psi/dscparse.c | 10 +-
psi/imainarg.c | 4 +-
psi/int.mak | 2 +-
psi/msvc.mak | 47 ++-
psi/zfilter.c | 7 +
windows/ghostpdl.vcproj | 24 ++
windows/ghostscript.vcproj | 20 ++
xps/xpsimage.c | 1 +
xps/xpsjxr.c | 26 +-
xps/xpstop.c | 1 +
112 files changed, 3263 insertions(+), 570 deletions(-)
create mode 100644 contrib/gdevadmp.c
create mode 100644 gpdl/image/imagetop.c
delete mode 100644 gpdl/psi/gpdlpsi.mak
create mode 100644 gpdl/pwg/pwgtop.c