Is using multiple halftone screens on the same page allowed in postscript 3? - ghostscript

I am working with a postscript file that uses sethalftone several times on the same page. On my printer I get the expected results but when using ghostscript, the whole page is rendered with the same screen. I reduced it down to this example:
%!PS-Adobe-3.0
<< /PageSize [99 33] >> setpagedevice
/size 33 def
/rect {
newpath
0 0 moveto
size 0 lineto
size size lineto
0 size lineto
closepath
fill
} def
0.5 0.5 0.5 0.5 setcmykcolor
rect
<< /HalftoneType 1 /Frequency 100 /Angle 60 /SpotFunction { pop } >> sethalftone
size 0 translate
rect
<< /HalftoneType 1 /Frequency 100 /Angle 45 /SpotFunction { pop } >> sethalftone
size 0 translate
rect
showpage
For which gs -dNOPAUSE -dBATCH -r600 -sDEVICE=tiffsep1 -sOutputFile=test%d.tif test.ps (version 9.52) gives me the following channel images (its the same for all channels):
When moving the first sethalftone before the first rect command, I get these channel images, which contain artifacts and still have the same halftone:
Obviously, there is some sort of memory corruption in the halftone buffer.
Setting only one halftone at the beginning (before the default has been used) works fine.
So my question from the title remains: Is it allowed to use multiple different halftones on the same page in postscript?
PS: When separating each rectangle and halftone onto its own page, I still get the memory corruptions but the halftones seem to be applied differently.

You can change halftone at any point in the course of a PostScript program. It need not be at the start of a page or start of a program.

Related

Unscrambling rotation of jpeg concentric pixel blocks

As part of a 'Capture The Flag' challenge the attached jpg was scrambled to obscure the content. The image ("flagpoles.jpg") is 1600 pixels by 1600 pixels. The concentric lines appear to have a blocksize of 10 pixels wide. (It resembles a Frank Stella painting). It appears the original image has been split into four portions which are arranged symmetrically around the center. I have been trying to write a python script to work through the pixels and unscramble the concentric squares. My efforts have resulted in two useless recurring conditions, either no change or increased scrambling. I think this might be because I am working on the entire image and it might be better to try and unscramble part of it. Here is the code I have. At the moment it only processes half of the pixels because I am trying to match up portions of the picture with each other. I tried sending the blocks to the other side of the image to try and match them up, but there is no improvement. Any assistance in getting a clear picture would be gratefully received.
from PIL import Image
import math
im = Image.open("flagpoles.jpg", "r")
pic = im.load()
def rot(A, r, x1, y1):
myArray = []
for i in range(r):
myArray.append([])
for j in range(r):
myArray[i].append(pic[x1+i, y1+j])
for i in range(r):
for j in range(r):
pic[x1+i,y1+j] = myArray[r-1-i][r-1-j]
xres = 800
yres = 800
blocksize = 10
for i in range(blocksize, blocksize+1):
for j in range(int(math.floor(float(xres)/float(blocksize+2+i)))):
for k in range(int(math.floor(float(yres)/float(blocksize+2+i)))):
rot(pic, blocksize+2+i, j*(blocksize+2+i), k*(blocksize+2+i))
im.save("hopeful.png")
print("Finished!")
The image seems to consist of concentric square boxes of width 10 pixels, each rotated by 90° relative to the previous one. After every four rotations, the pixels are once again oriented in the same direction.
You can easily undo this by making a copy of the image and repeatedly rotating by 270° while cropping away a 10 px border. Paste these rotated images back into the corresponding locations to retrieve the original image.
from PIL import Image
step_size = 10
angle_step = 270
img = Image.open("flagpoles.jpg", "r")
img.load()
w = img.width
assert img.height == w
img_tmp = img.copy() # Copy of the image that we're going to rotate
offset = 0 # Coordinate where the rotated images should be pasted
cropmax = w - step_size # Maximum coordinate of cropping region
while cropmax > step_size:
# Rotate the copy of the image
img_tmp = img_tmp.rotate(angle_step)
# Paste it into the original image
img.paste(img_tmp, (offset,offset))
# Crop a 10 px border away from the copy
img_tmp = img_tmp.crop((step_size, step_size, cropmax, cropmax))
# Update the crop position and width for the next iteration
cropmax -= step_size * 2
offset += step_size
img.save("fixed.jpg")

PDF cropping image almost correctly

I've inherited some code that hand-rolls PDF files. One of the things this code does, is that a large image is inserted into the PDF as a resource, and then pieces of that image are cropped in the PDF command stream and drawn separately.
For example, if the large image is 1000 x 400 pixels, the code draws a chunk extracted from the top left of the large image ((0, 0) to (250, 200)) and then next to that draws another chunk extracted from the top middle of the large image ((250, 0), (500, 200)) (in this post I'm describing the crop coordinates using standard image coordinate system with origin in top-left).
The way the code does this, is to create a secondary XObject that just draws the large image, scaled and offset appropriately. So to extract the image from ((250, 0) to (500, 200)) it defines a new XObject like this:
/Type/XObject /Subtype/Form /FormType 1 /Name/Img4 /BBox [0 0 1 1] /Matrix [1 0 0 1 0 0] /Length 26/Resources << /XObject << /img3 23 0 R >> >>
4 0 0 2 1 1 cm
/img3 Do
(obviously I've cut out a lot of PDF, don't worry, it works so the PDF you don't see is basically correct)
Which, if I understand it correctly, takes the XObject of the original image (which is a 1 x 1 square), makes it 4 times bigger in the x-direction and 2 times bigger in the y-direction, offsets it by 1 in both x and y, and now the portion of the image we want appears in the XObject rectangle of ((0, 0), (1, 1)). So the code can just draw this new XObject wherever it wants, and gets the cropped portion of the large image.
This basically works correctly, but of course in the real world the large image is 656 x 656, and the pieces being extracted are 308 x 120 and 40 x 120 so the numbers aren't quite as nice.
If I look at the resulting PDF at high magnification (1600%) in Adobe Acrobat Reader, it's perfect. All the pixels exactly where they should be.
The problem I'm running into, is that at lower magnification (200%), I end up with this strange offset where the 2 images abut:
For this example, the transform matrix that does the cropping is:
2.12987 0 0 5.46667 -0 -4.46667 cm
which seems like it should be enough digits of precision, but even if I increase the precision:
2.1298701 0 0 5.4666667 -0 -4.4666667 cm
the exact same problem happens.
It looks like Adobe Reader is truncating the precision somewhere in its calculations.
Any idea why this is happening, and how I can get around it?

How to process a "Very Large image file" in MATLAB and find out the pixel with largest value

I have to process a very large image ( say 10 MB image file or even more).I have to remove artifacts and dead pixels in MATLAB
I have read about Block Processing of Large Images, but have no idea how to apply it to a 16 bit image.
I am referring to removal of pixels which have highest value into the average value of surrounding pixel .my code is not working on my image which is 80 MB of size
numIterations = 30;
avgPrecisionSize = 16; % smaller is better, but takes longer
% Read in the image grayscale:
originalImage = double(rgb2gray(imread('C:\Documents and Settings\admin\Desktop\TM\image5.tif')));
% get the bad pixels where = 0 and dilate to make sure they get everything:
badPixels = (originalImage == 0);
badPixels = imdilate(badPixels, ones(12));
%# Create a big gaussian and an averaging kernel to use:
G = fspecial('gaussian',[1 1]*100,50);
H = fspecial('average', [1,1]*avgPrecisionSize);
%# User a big filter to get started:
newImage = imfilter(originalImage,G,'same');
newImage(~badPixels) = originalImage(~badPixels);
% Now average to
for count = 1:numIterations
newImage = imfilter(newImage, H, 'same');
newImage(~badPixels) = originalImage(~badPixels);
end
%% Plot the results
figure(123);
clf;
% Display the mask:
subplot(1,2,1);
imagesc(badPixels);
axis image
title('Region Of the Bad Pixels');
% Display the result:
subplot(1,2,2);
imagesc(newImage);
axis image
set(gca,'clim', [0 255])
title('Infilled Image');
colormap gray
newImage2 = roifill(originalImage, badPixels);
figure(44);
clf;
imagesc(newImage2);
colormap gray
You are doing a few things which are obvious problems (but it might depend specifically on how far you can get into the code before you run out of memory)
1) You are immediately converting the whole image to double
2) You are identifying certain pixels which you want to replace, but passing the whole image to imfilter and then throwing away (presumably) most of the output:
newImage = imfilter(originalImage,G,'same'); % filter across the entire image
newImage(~badPixels) = originalImage(~badPixels); % replace all the good pixels!
Without converting to double, why not first check where the bad pixels are, do your processing on subregions of the appropriate size around those pixels (the subregions can be converted to double and back), and then reassemble the image at the end?
blockproc may work if you can write your filtering option as a function which takes in an image area and returns the correct area - you'll have to use the border_size option appropriately and make sure your function just returns the original image without bothering to do any filtering if it hits a block with no bad pixels in. You can even have it write out to file as well.

problematic Moire pattern in image produced with gnuplot pm3d and pdf output

I'm plotting data using the command files discussed here:
gnuplot contour line color: set style line and set linetype not working
I want to provide different output options. PNG works well, as does the wxt terminal, however, these have fixed resolution, e.g. when I "zoom in" on the plot it gets grainier.
If I use pdf or pdfcairo for the terminal, the resulting file has a Moire pattern. The region in the image over which the Moire pattern is observed can be reduced by using increasing amounts of interpolation in the pm3d command. There are lots of points in the data set in the radial direction, but not many angular sets of data, so I need to interpolate more in that "direction". Using no interpolation results in a very grainy pm3d image, so I have been trying 0,20 to 20,20 or even 20,40. Unfortunately even lots of interpolation does not completely get rid of the Moire pattern, makes the file size HUGE (e.g. the PNG file is around 250kB but the pdf file is over 11MB) and as a result it renders very slowly. I've tried viewing these with Adobe Acrobat Reader 10.1.8 and GSview and the result is the same.
I am interested in using the pdf format because it is ubiquitous and can be zoomed in without excessive loss of detail (unlike PNG).
Below are a couple of screen shots that I captured of the pattern in the resulting pdf output at different levels of interpolation. The first image is the png file for reference as it shows no Moire pattern, 250kB file size.
Next, the pdf output without pm3d interpolation, 72kB file size:
Next, the pdf output using set pm3d map interpolate 0,20, file size 1861kB:
Next, the pdf output using set pm3d map interpolate 10,20, file size 5942kB:
Finally, the pdf output using set pm3d map interpolate 20,20, file size 11515kB:
Why are these Moire patterns generated for the pdf outputs? Is there away around this, that would allow me to still have a vector format that can be zoomed in without (much) loss of resolution?
This is not supposed to be a solution, but rather an explanation and a possible, although ugly workaround.
From time to time there are reports to the gnuplot mailinglists about this issue, but it seems to be related to the viewers. It has to do with the way gnuplot creates the surfaces plots. These are drawn as polygons, which are stitched together. The Moiré patterns you are showing come from wrong rendering between two polygons. That depends on the viewer, the viewer settings and the zoom factor.
The easiest example, to show that effect is the following Postscript file:
%!PS-Adobe-2.0
50 50 moveto 50 0 rlineto 0 50 rlineto -50 0 rlineto closepath 0 setgray fill
100 50 moveto 50 0 rlineto 0 50 rlineto -50 0 rlineto closepath 0 setgray fill
Save this file e.g. as moire.ps and view it, or convert it with ps2pdf and view it. With the Acrobat reader 9.5.1 I see the following:
The Acrobat Reader has a setting Preferences -> Page Display -> Enhance thin lines which can prevent this problem, but causes problems on other parts.
On my system (Debian), all viewers show this patterns, mupdf, firefox, ghostscript, pdftocairo, libpoppler` etc.
So, what to do? For myself I use the following workaround. I splot to a png with high resolution, and reread that file later with plot ... with rgbimage. Then you get your heatmap as bitmap, and the rest is vectorial. In most cases this is no problem, because in any way you have some measurement data with limited resolution, which you interpolate.
Based on the question gnuplot contour line color: set style line and set linetype not working, here is how you can implement it:
reset
set lmargin at screen 0.05
set rmargin at screen 0.85
set bmargin at screen 0.1
set tmargin at screen 0.9
set pm3d map interpolate 20,20
unset key
set cntrparam bspline
set cntrparam points 10
set cntrparam levels increment -6,-6,-24
set contour surface
set linetype 1 lc rgb "blue" lw 2
set linetype 2 lc rgb "blue"
set linetype 3 lc rgb "black"
set linetype 4 lc rgb "orange"
set linetype 5 lc rgb "yellow"
set palette rgb 33,13,10 #rainbow (blue-green-yellow-red)
set cbrange [-18:0]
unset border
unset xtics
unset ytics
set angles degree
r = 3.31
set xrange[-r:r]
set yrange[-r:r]
set colorbox user origin 0.9,0.1 size 0.03,0.8
##################### start changes ##############
set autoscale fix
RES_X = 2000
RES_Y = 2000
save('settings.tmp')
set lmargin at screen 0
set rmargin at screen 1
set bmargin at screen 0
set tmargin at screen 1
unset colorbox
set terminal pngcairo size RES_X, RES_Y
set output '3d-polar-inc.png'
splot 'new_test.dat' nocontour
unset output
load('settings.tmp')
# mapping of the coordinates for the png plotting later
X0 = GPVAL_X_MIN
Y0 = GPVAL_Y_MIN
DX = (GPVAL_X_MAX - GPVAL_X_MIN)/real(RES_X)
DY = (GPVAL_Y_MAX - GPVAL_Y_MIN)/real(RES_Y)
C0 = GPVAL_CB_MIN
DC = GPVAL_CB_MAX - GPVAL_CB_MIN
C(x) = (x/255.0) * DC + C0
# now plot the png
#set terminal pdfcairo size 10cm,10cm
#set output '3d-polar.pdf'
set terminal postscript eps color level3 size 10cm,10cm solid
set output '3d-polar-eps.eps'
set multiplot
set cbrange[GPVAL_CB_MIN:GPVAL_CB_MAX]
plot '3d-polar-inc.png' binary filetype=png \
origin=(X0, Y0) dx=DX dy=DY \
using (C($1)):(C($2)):(C($3)) \
with rgbimage, \
NaN with image t '' # hack for getting the colorbox
# plot the contours
unset surface
unset pm3d
splot 'new_test.dat' w l
###################### end changes #################
# now plot the polar grid only
set style line 11 lc rgb 'black' lw 2 lt 0
set grid polar ls 11
set polar
set logscale r 10
set rrange[10:20000]
unset raxis
set rtics format '' scale 0
#set rtics axis scale
set rtics (20,50,100,200,500,1000,2000,5000,10000,20000)
do for [i=-150:180:30] {
dum = r+0.15+0.05*int(abs(i/100))+0.05*int(abs(i/140))-0.05/abs(i+1)
set label i/30+6 at first dum*cos(i), first dum*sin(i) center sprintf('%d', i)
}
set label 20 at first 0, first -(log(20)/log(10)-1) center "20"
set label 100 at first 0, first -(log(100)/log(10)-1) center "100"
set label 200 at first 0, first -(log(200)/log(10)-1) center "200"
set label 1000 at first 0, first -(log(1000)/log(10)-1) center "1k"
set label 2000 at first 0, first -(log(2000)/log(10)-1) center "2k"
set label 10000 at first 0, first -(log(10000)/log(10)-1) center "10k"
set label 20000 at first 0, first -(log(20000)/log(10)-1) center "20k"
plot NaN w l
unset multiplot
unset output
With pdfcairo this gives a 1.7 MB pdf file, with epslatex level3 (this option is available in the 4.7 development version only) you get a 1.5 MB eps file, which can be converted with epstopdf to a 136 KB pdf file.
See also my answer to Big data surface plots: Call gnuplot from tikz to generate bitmap and include automatically? on TeX.SX.

Programatically How do I reset colors in PDF

I am creating a PDF file and I would like to generate several rectangles on the page
However once I fill a rectangle in color I cannot reset the fill color (non-stroking color) to
clear, white, transparent or whatever is needed so that no color is in the rectangle
I use this to set the stroke and non-stroke to red
1.0 0.0 0.0 rg
1.0 0.0 0.0 RG
I set the line width
1 w
I draw a rectangle and it appears as a red rectangle (outlined and filled in red)
0046.8 0633.6 0237.6 0100.8 re
B
Now I set the stroke to black
0.0 0.0 0.0 RG
I attempt to create another rectangle (I only want black outline)
0072.0 0576.0 0288.0 0144.0 re
B
But the second rectangle appears with a black outline but is filled in red?
How do I get red of the red fill?
Your problem is your use of B. If you interchange the two drawing operations you'll see that (what was) the second rectangle is now filled with black, because black is the default color. You should use S for the second rectangle, so that that path is stroked but not filled.
By the way, you're missing some really easy ways to reduce the size of your generated PDF:
Use g/G instead of rg/RG when all three numbers are the same.
1 w is unnecessary (unless returning to that setting from a different one), 1 is the default value for stroke width.
Don't print trailing .0 or leading zeroes on your numbers.
Putting all which together, here's what your generated page stream should look like:
1 0 0 rg 1 0 0 RG
46.8 633.6 237.6 100.8 re B
0 G
72 576 288 144 re S

Resources