Ghostscript /stackunderflow in CMap definition - ghostscript

I'm trying to create a simple CMap with mapping for two CIDs. Any idea what's wrong with following CMap?
/CIDInit /ProcSet findresource begin
13 dict begin
begincmap /CIDSystemInfo <<
/Registry (Adobe) /Ordering (Identity) /Supplement 0 >> def
/CMapName /CM def
/CMapType 1 def
1 begincodespacerange
<00> <02>
endcodespacerange
2 begincidchar
<01> 6691
<02> 6692
endcidchar
endcmap CMapName currentdict /CMap defineresource
pop end end
gs interpreter throws following error:
Error: /stackunderflow in --index--
Operand stack:
1 --nostringval-- (\002) 6691 (\001) (\000\000\000\002) () (\032#) 0 (\001) 10
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1992 1 3 %oparray_pop 1991 1 3 %oparray_pop 1979 1 3 %oparray_pop 1833 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- 1 --nostringval-- %repeat_continue --nostringval-- --nostringval--
Dictionary stack:
--dict:730/1123(ro)(G)-- --dict:0/20(G)-- --dict:75/200(L)-- --dict:38/38(ro)(G)-- --dict:8/13(L)--
Current allocation mode is local
Current file position is 270
GPL Ghostscript 9.27: Unrecoverable error, exit code 1

This was a bug which is fixed now.
For individual code mappings (endnotdefchar/endcidchar) we check if the
previous mapping values are adjacent to the current one, so we can optimize by
merging them into a range. Each map involves 5 entries on the stack, and the
check to trigger the attempt to merge checked for >5 entries on the stack. That
works as long as the number of mappings is large enough that we always have at
least 10 entries (the merging code will cope with unprocessed entries).
In this case, we only have two mappings, when we reach the check for a marge
condidate, there are seven entries on the stack (5 for the current, 2 for the
remaining mapping), and we end up with a stackunderflow error, because code
expects at least 10 objects on the stack.
Thanks #chrisl

Related

How to apply not operator to all matrix elements in Julia?

I need to apply "not" operator to matrix of zeros and ones in Julia.
In Matlab I would do this:
A=not(B);
In Julia I tried doing this:
A = .~ B;
and
A = .! B;
It should turn zeros to ones and ones to zeros but I get error as a result or all matrix elements are some negative numbers that I didn't enter.
Thanks in advance!
The issue with A = .!B is that logical negation, !(::Int64), isn't defined for integers. This makes sense: What should, say, !3 reasonably give?
Since you want to perform a logical operation, is there a deeper reason why you are working with integers to begin with?
You could perhaps work with a BitArray instead which is vastly more efficient and should behave like a regular Array in most operations.
You can easily convert your integer matrix to a BitArray. Afterwards, applying a logical not works as expected.
julia> A = rand(0:1, 5,5)
5×5 Array{Int64,2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> B = BitArray(A)
5×5 BitArray{2}:
0 0 0 1 1
0 1 0 0 1
0 1 1 1 0
1 1 0 0 0
1 1 1 0 0
julia> .!B
5×5 BitArray{2}:
1 1 1 0 0
1 0 1 1 0
1 0 0 0 1
0 0 1 1 1
0 0 0 1 1
The crucial part here is that the element type (eltype) of a BitArray is Bool, for which negation is obviously well defined. In this sense, you could also use B = Bool.(A) to convert all the elements to booleans.
For a general solution to going from A where A is a matrix of numbers to a boolean matrix with true values where there were zeros and false values elsewhere, you can do this:
julia> A = rand(0:3, 5, 5)
5×5 Array{Int64,2}:
1 0 1 0 3
2 0 1 1 0
2 1 1 3 1
1 0 3 0 3
1 3 3 1 2
julia> (!iszero).(A)
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
To break down what's going on here:
iszero is a predicate that tests if a scalar value is zero
!iszero is a predicate that returns if a scalar value is not zero
(!iszero).(A) broadcasts the !iszero function over the matrix A
This returns a BitArray with the desired pattern of zeros (falses) and ones (trues). Note that in an array context, false prints as 0 and true prints as 1 (they are numerically equal). You can also compare with the number 0 like this:
julia> A .!= 0
5×5 BitArray{2}:
1 0 1 0 1
1 0 1 1 0
1 1 1 1 1
1 0 1 0 1
1 1 1 1 1
You can also roll your own:
not(x) = (x |> Bool |> !) |> Float64
defines a method that will convert x to boolean, apply not, and then convert the result back to numbers. not.(A) will act element-wise on the array A. Here |> redirects the output to the next method and works with broadcasting.
While not conceptually the cleanest, A=1.-B will do what you want. The problem with ~ is that it is performing a bitwise not on integers, which produces negative numbers. Not sure what is wrong wiht ! except it maybe should be !.B

error in conversion of raster file to postscript file

I am trying to convert PWG raster file data into postscript data. I have generated at test file which is as follows:
%!PS-Adobe-3.0
%%BoundingBox: 0 0 5100 6600
%Creator: Cups-Filters
%LanguageLevel: 2
%DocumentData: Clean7Bit
%EndComments
%BeginProlog
%EndProlog
%Pages: (atend)
%%Page: 1 1
%%BeginPageSetup
<< /PageSize[5100 6600]/ImagingBBox null>> setpagedevice
%%EndPageSetup
gsave
gsave
5100 6600 scale
5100 6600 8 [5100 0 0 -6600 0 6600]
{currentfile 3 5100 string readhexstring pop} bind
false 3 colorimage
...hexadecimal information cut...
grestore
showpage
%PageTrailer
%Trailer
%%Pages: 1
%EOF
Whenever I try to run the program using GhostScript interpretor, I get the following error:
$ ghostscript sample.ps
GPL Ghostscript 9.18 (2015-10-05)
Copyright (C) 2015 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Error: /typecheck in --colorimage--
Operand stack:
--nostringval-- 3 (\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000...)
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1977 1 3 %oparray_pop 1976 1 3 %oparray_pop 1960 1 3 %oparray_pop 1852 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- 1878 7 3 %oparray_pop
Dictionary stack:
--dict:1194/1684(ro)(G)-- --dict:0/20(G)-- --dict:78/200(L)--
Current allocation mode is local
Current file position is 399
GPL Ghostscript 9.18: Unrecoverable error, exit code 1
The PS file is about 128 MB with about 99% data being the hexadecimal representation of the coloured image.
I tried searching it and one source suggested to add 'setpagedevice' parameter to the PS file. I have added it but to no effect.
How can I get rid of this error ? Also, is there any other way to represent very large images in postscript ?
Your code contains:
{currentfile 3 5100 string readhexstring pop} bind
If we break that up and add comments about the stack content we get:
{
currentfile % Stack contents: -file-
3 % stack contents: -file- 3
5100 % stack contents: -file- 3 5100
string % string consumes the top operand, creates a string
% object of that size, and places the string on the stack
% stack contains: -file- 3 (string)
readhexstring % consume string and file operands, return substring, bool
%
pop % pop the boolean
}
The problem is that readhexstring expects to see -file- (string) but the stack actually contains 3 (string), 3 isn't a file object so you get a typecheck error.

Sum stack without last element

is there a possibility to sum up the stack without the last element? So for example if the stack has the following elements:
1 2 3 4 5
After the operation the stack should look like this:
1 14
USE: generalizations
1 2 3 4 5 datastack length 1 - nsum

APL find frequency of elements in a matrix

I have this piece of code
((⍳3)∘.+(⍳2))
which generates the following matrix
2 3
3 4
4 5
I want to find the occurrence of each unique element in the result i.e occurrence of 2,3,4,5 in the result.
I tried using "∘.=" with the matrix itself and then reshaping such that elements of each sub matrix is transformed into a row
using
6 6⍴ ((⍳3)∘.+(⍳2))∘.=((⍳3)∘.+(⍳2))
which gives the following result
1 0 0 0 0 0 for 2
0 1 1 0 0 0 for 3
0 1 1 0 0 0 for 3
0 0 0 1 1 0 for 4
0 0 0 1 1 0 for 4
0 0 0 0 0 1 for 5
as you can see it still contains the sum for duplicate items, and I'm lost as of now.
Any help will be appreciated.
You should do ∘.= between the unique elements in the matrix and a flat vector of all elements, like:
m ← ((⍳3)∘.+(⍳2))
(∪,m) ∘.= ,m
1 0 0 0 0 0
0 1 1 0 0 0
0 0 0 1 1 0
0 0 0 0 0 1
Then just do +/ on it to get the frequencies of ∪,m
+/ (∪,m) ∘.= ,m
1 2 2 1
∪,m
2 3 4 5
(Tested on GNU APL.)
Dyalog APL version 14.0 has the ⌸ Key operator exactly for this, you just need to ravel your data:
{≢⍵}⌸ ,((⍳3)∘.+(⍳2))
1 2 2 1
Try it online!
You can even use the left argument of ⌸'s operand function to create a table:
{⍺,≢⍵}⌸ ,((⍳3)∘.+(⍳2))
2 1
3 2
4 2
5 1
Try it online!

Ghostscript error limitcheck in string

Why is the final part of my PDF creation process failing please. See output from ps2pdf command below. This is at the end of my own developed tool chain. I harvest images from Matlab, stitch them together using LaTeX and then create the final PDF using latexmk.
This has worked fine until now when the document in question has grown to 3356 pages!
File position 238282 in file output.ps (as mentioned in the ghostscript error output) is towards the end of the "SDict begin [ {Catalog} << /PageLabels<>1<>2 " line. This line is 51542 chars long and describes all 3356 pages.
Is this line length just too long now? If I trim my .tex file down towards 3000 pages and re-run the latexmk it completes fine.
Running ps2pdf in isolation to show error. Same error when run from latexmk:
C:\temp>c:\MiKTeX\miktex\bin\ps2pdf.exe output.ps output.pdf > error.txt 2>&1
Gave output:
Error: /limitcheck in --string--
Operand stack:
--nostringval-- --nostringval-- --dict:1/1(L)-- PUT --nostringval-- 2 --nostringval-- 2 false --nostringval-- --nostringval-- (]) --nostringval-- --nostringval-- (3327) --nostringval-- --nostringval-- P 1 .pdfcvstring (<<\n/P \(3225\)\n>> 3226 <<\n/P \(32) (<<\n/Nums [0 <<\n/P \(1\)\n>> 1 <<\n/P \(1\)\n>> 2 <<\n/P \(2\)\n>> 3 <<\n/P \(3\)\n>> 4 <<\n/P \(4\)\n>> 5 <<\n/P \(5\)\n>> 6 <<\n/P \(6\)\n>> 7 <<\n/P \(7\)\n>> 8 <<\n/P \(8\)\n>> 9 <<\n/P \(9\)\n>> 10 <<\n/P \(10\)\n>> 11 <<\n/P \(11\)\n>> 12 <<\n...) 65550
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1910 1 3 %oparray_pop 1909 1 3 %oparray_pop 1893 1 3 %oparray_pop 1787 1 3 %oparray_pop --nostringval-- %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- 1917 4 5 %oparray_pop --nostringval-- 3 1 2 --nostringval-- %for_pos_int_continue --nostringval-- --nostringval-- --nostringval-- --dict:1/1(L)-- --nostringval-- 1 %dict_continue --nostringval-- --nostringval-- --nostringval-- --nostringval-- %array_continue --nostringval-- --nostringval-- --dict:1/1(L)-- --nostringval-- 1 %dict_continue --nostringval-- --nostringval-- %zwritecvp_continue 1 %s_proc_write_continue --nostringval-- --nostringval-- --nostringval-- --nostringval--
Dictionary stack:
--dict:1159/1684(ro)(G)-- --dict:0/20(G)-- --dict:81/200(L)-- --dict:188/300(L)-- --dict:36/200(L)-- --dict:10/10(G)--
Current allocation mode is local
Last OS error: No such file or directory
Current file position is 238282
MiKTeX GPL Ghostscript 9.00: Unrecoverable error, exit code 1
Edit: Added my complete page labels line from the postscript file that goes into ps2pdf. See pastebin entry http://pastebin.com/FFvZpaRY
I ran pdfmark you provided with 9.10's pdfwrite device without error, but 9.00 fails with the same message as you show.
Ghostscript has been extended to support Postscript string and array
objects with >64k entries.
Update:
Assuming, that page labels you need are 1,1,2,3...3261 (don't know why, but that's what is in your example), it's simpler to add auto-incrementing numeric labels, not string prefixes as you do.
[{Catalog}<<
/PageLabels<</Nums[0<</S/D>>1<</S/D>>]>>
>> /PUT pdfmark
Or, if prefixes are what's necessary, split your big array into two or more:
[/_objdef{leaf1}/type/dict/OBJ pdfmark
[/_objdef{leaf2}/type/dict/OBJ pdfmark
[{leaf1}<</Limits[0 3000]
/Nums[
... 0 to 3000 labels go here ...
>>/PUT pdfmark
[{leaf2}<</Limits[3001 3261]
/Nums[
... 3001 to 3261 labels go here ...
>>/PUT pdfmark
[{Catalog}<</PageLabels<</Kids[{leaf1} {leaf2}]>>
>>/PUT pdfmark
Both these solutions work with 9.00

Resources