-
-
Notifications
You must be signed in to change notification settings - Fork 364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libpng 1.6.2 not working properly with AGG / MapServer 6.2? #4722
Comments
|
interesting find... I believe the artifacts you are seeing are happening because you are way out of bounds of the designed use-cases for pixmap symbols; mapserver uses bilinear resampling when scaling images, which fails miserably for the scaling you are applying to your input pixmaps. We might look into adding additional filters when the scaling is far away from the designed limits (i.e. a scaling by a factor of around 2), however this isn't high priority as you should not be scaling or rotating pixmap symbols in the first place, for questions of quality and performance.
|
|
and for the record, this has effectively nothing to do with libpng, and the "dropouts" that are seen are very probably not due to arithmetic overflows, but the resampling picking one of the gray outlines from the original png. |
|
Thomas, I must say that in the example we have a scale of >100,000 but I does that at every scale till < 1000 whilst before it rendered the symbol clearly. |
|
@r-robert it was not doing a good job, it was doing a better job that was still far from satisfying :). Your old examples are using the GD renderer, the AGG pixmap resampler has always behaved as today. As for your map scales, they are irrelevant here; the scaling I'm referring to is the downsampling from a 299x299 pixmap to a 21x21 (or 25x25, 30x30, etc) one. |
|
@tbonfort I just checked with a re-sized version of the icons and it looks ok. |
|
@tbonfort just a quick follow-up: I would like to know if I can make use of the GD renderer in this case like before (although I think it is going to be removed?). I am asking because I have more than 400 png symbols on a bunch of maps. I used them this way because it worked thus I would prefer to make it work like it did instead if replacing all the png files. |
|
You have many ways to treat this, even if you insist on using pixmap symbols which are not designed for this. (e.g. create an imagemagick script that resizes your pixmaps to 20x20, 30x30 and 40x40). You can still use GD with 6.2, although it is basically unmaintained and is being dropped completely in the next release. Having mapserver rescale a 300x300 image down to 20x20 for each feature is also very inefficient. |
|
Dropouts: the filter kernel size is determined by the lowest sample rate. In the case in question the input and output widths are 299 and 16 respectively. The filter is bilinear, so the width is 1 in the output and 19 in the input. That means that only the outermost pixels in the output had the case where the filter overlaps the edge of the image. One classic filtering bug is not to take this into account - the filter weight has to be calculated specially for the edge because the sum of weights no longer adds up to 1.0, however I don't think this is happening because the dropouts are 3 pixels into the output and are not symmetric. Nevertheless I couldn't see where the AGG 2.5 code adjusts the filter weight (I didn't look very hard.) Unsymmetric output: that suggests and off-by-half error. The only way I know to get this right without excessive complexity (which leads to errors) is to regard input and output samples as sited at (0.5,0.5) in their own sample space. This means that the edge pixels of the output end up with alpha, but then this must happen if the image size is not to be changed. (So the input sample at (0.5,0.5) is mapped to output symbol at (0.5,0.5) and the input sample at (w_input-0.5,h_input-0.5) is mapped to the output at (w_output-0.5,h_output-0.5; this is slightly counter-intuitive but it does actually avoid scaling by up to (w-0.5)/w!) Use of bilinear: bilinear performs the same whether scaling up or down, indeed it often looks a lot better when scaling down (as in this case). In fact it's a lousy filter; bicubic is so close to exact (the sinc filter is exact) that it's pointless using any other. There's often hardware support for something like bicubic. The result of using bilinear is that the images blur when scaled up and produce odd aliases when scaled down. Correct resampling: the aliases I was seeing in the original image suggest to me that the AGG code is filtering in an encoded space. This does not work and produces errors, regardless of filter, on a par with those in bilinear. Sample date must be converted to a linear space before resampling. Notice, also, that alpha data must be multiplied out; PNG stores alpha samples with the original colors (required for color correction), so each sample must be multiplied out after the color correction and before scaling: In the case in question where the input is sRGB this is pretty accurate (i.e. the arithmetic errors are small, though if you were to use a sinc() filter then doing the correct inverse-sRGB transform might be worthwhile): Since the gamma (or sRGB encoding) has to be inverted before doing the alpha composition, and alpha has to be multiplied out, it's just a matter of doing everything in the correct order. I don't know what is going wrong in the original case, but something seems to be up. Finally; is it really bilinear? I don't think so, looks more like Fant to me, because the 'bad' image has apparently been resampled with a block filter. That's what Fant degrades to on large down-scales. John Bowler jbowler@acm.org |
|
@tbonfort I understand better now. Considering all this, don't you think that it would be a good addition to add better functionality for these types of data? It's true that I am considering my working environment but the maps really look nice when you put an icon to represent something. In this case, it is easier (for us) to deal with png files. It would be a great addition if the resizing could be done well in mapserver compared to the other option of having 3 png files representing the same thing. I am unaware how difficult it would be though to add this extra functionality. |
|
I second the last r-robert comment; downscaling large images correctly certainly involves much more CPU/output-pixel but I feel that is a much better compromise that downscaling incorrectly and achieving better CPU/output-pixel. |
|
@jbowler, thanks for taking the time to write your previous explanation. @r-robert I'm still not convinced that using pixmap symbols is the best solution when rendering symbols in multiple sizes, given mapserver has two alternative symbol types that perform correctly for this use-case (namely svg and truetype). I however agree that there is room for improvement in this area. Is this something that you would be able to fund, either by contributing and then committing to maintain a patch for this, or by contracting me or another mapserver developer to do it for you ? |
|
@tbonfort I think I will let this float on the issue list for a while as it is out of my reach to fund this functionality for the moment. Maybe other users will pick up the idea and something will eventually be done. Thank you all for the info, |
|
@tbonfort one thing I could do is to contribute to the MapServer wesbite, like translating documentation or something like this. Would this work, or not really? |
|
@r-robert I'm not sure what you are trying to imply here... if you want to contribute to the doc site, be it by adding a comment about the (non)scalability of pixmap symbols, or any other contribution, then that will be greatly appreciated. However those contributions won't buy you the implementation of the scaling you need; we open-source developers are somewhat like other people, and also need to put food on our table, which is achieved by getting payed in hard money for those kinds of task :) |
|
@tbonfort I was not trying to imply anything, just to see if I can make this happen if I do not have funds or enough programming skills (yet); At first, I considered this issue more like an error that could be fixed instead of something new that should be added, because like I already said, the many years in which I worked with MapServer 5.0.0 it worked well. If it would have never worked well, maybe now I would have 400 svg icons instead of 400 png icons. Enough said, thanks for the info and support, |
Hello all,
I noticed that the output of legend and/or shp2img commands is quite different in my new setup (libpng 1.6.2 + MapServer 6.2) compared to what I had before (libpng 1.2.43 + MapServer 5.0).
The problem is related to PIXMAP symbols. The output is quite bad in the new setup, they just aren't as clear as they were before.
I attached a ".zip" file (zip extract password: libpng ) containing sample data to be used for testing purposes only. If you unzip the archive, from the resulted directory you can run the "shp2img -m test.map -o any_name.png -all_debug 5" command. It should work with all the paths in the mapfile. I used the same mapfile in both environments for testing purposes.
I also put the resulted ".png" files:
test_bad.png - was obtained using my new setting: libpng 1.6.2 + MapServer 6.2.1; it also displayed some errors related to sRGB profile;
test_good.png - was obtained using the old settings: libpng 1.2.43 and MapServer 5.0; clean output, no errors in the command line.
First I thought that maybe it has something to do with the libpng files but shooting an email regarding this issue to their mailing list ( http://goo.gl/XCjLLg ) I got an interesting answer:
Quoted Message:
Ok, I'll only post cropped sections of the images in this reply. My shp2img does not work at all, however this is moot because the problem is obvious from the output images (these are scaled up by a factor of 14 to make the problems obvious):
Inline image 1 (see attach)
The left image is a correctly resized version of one of the original symbol images. In the output files the symbols (which are stored as 299x299 24-bit RGBA PNG files) are resized to 16x16.
The middle image is from the old output ("test_good.png") and the right image is from the new output ("test_bad.png"):
There are gross errors in the resampling (resizing) code in the version of mapserver (shp2img) that you are using. While the original (mapserver 5.0) code was not correct either - I can see aliases in the test_good.png image - it was a lot better than the resizing in test_bad.png where there are obvious dropouts. For example the dark pixels at the top and right of the red cross suggest that arithmetic overflow is happening in the calculations.
This is apparently a change in mapserver, however I notice that the 'good' output is an interlaced PNG while the 'bad' output does not have interlacing. In the test.map file you sent me the OUTPUTFORMAT entries all have 'FORMATOPTION "INTERLACE=ON"' and the shp2img command does not have a '-i' option:
shp2img -m test.map -o any_name.png -all_debug 5
So the problem could be a change in the interpretation or defaulting of the output file format when there is no '-i'.
It might also be a change in the default resampling filter (resizing code) used. The AGG renderer used in mapserver apparently has support for a large number of different filters - maybe the default changed? All the same, no filter should product dropouts like those seen in test_bad.png, so I think there must be a bug anyway.
The bad iCCP profile in the original symbol files doesn't affect this. In fact I think the color space information is being ignored completely - this would explain the errors in the test_good.png image.
End Quoted Message
I appreciate any help I can get,
Inline image:

Zip File (extract password: libpng ):
http://speedy.sh/GqvYH/libpng16.zip
The text was updated successfully, but these errors were encountered: