On Thursday, October 31, 2013 1:14:57 AM UTC+1, Nigel Tao wrote:

Hi. I'm the author of Go's standard image library.

Hi Nigel. Don't take me wrong, it's great that Go has image related
packages in the standard library, which are getting better by the day. I'm
sure they work fine for a lot of people, and that number is only going to
increase. However, right now, if you have advanced needs, like decoding
every possible image that a user might throw at you or work with animated
GIFs, Go's standard library is not there yet.

On Thu, Oct 31, 2013 at 3:29 AM, Alberto García Hierro
<alb...@garciahierro.com <javascript:>> wrote:
In our performance tests, we've found that GM is around 120x faster than the
image related modules in the standard library when it comes to
decoding/resizing/cropping/encoding images.
120x surprises me. Do you have some example Go code and test data that
shows this?
One thing is that newcomers to Go's standard library often use the
generic At and Set methods in their inner loops, which are the easiest
to use but slower, and definitely not how I would e.g. do resizing or
cropping. For example,
describes a 3x speed-up by using the Pix field directly.
One of the tests is even in the magick package. Using GM it is 129x times
faster, while IM is 93x. For this benchmark we're using
http://github.com/nfnt/resize, which seems to access the Pix field
directly, although it calls an interface method in the inner loop.

fiam@ubuntu:~/gocode/src/magick$ go test -v -tags gm -run=TestDecode$
=== RUN TestDecode
--- PASS: TestDecode (0.25 seconds)
magick_test.go:90: Using backend GraphicsMagick
BenchmarkResizePng 20 72172794 ns/op
BenchmarkResizePngNative 1 9352362699 ns/op

On Thu, Oct 31, 2013 at 5:32 AM, Alberto García Hierro
<alb...@garciahierro.com <javascript:>> wrote:
The only benefit would be able to run on environments when using
cgo/unsafe is not allowed (like GAE), but I personally have zero
interest in
Another benefit is that decoding untrusted, third party images is far
less likely to result in remote code execution through buffer
overflows, as Go is a memory-safe language, but I don't know how
important that is to you.

Truth to be told, almost zero. If someone were to target us specifically,
I'm sure there are 0-days in other services
running on our servers. Even our own code could have security holes, we're
all humans after all. It is nice to close a potential attack vector, but
when closing it comes with very significant tradeoffs and you still have a
bunch of other vectors open, it's not worth it.

all image/* packages failed to decode 20-30% of our sample set),
20-30% also sounds surprisingly large to me. Can you send me some of
these failed images (off-list)? How many of these are 'optimized
Keep in mind that this was in August 2012 and I'm sure the situation has
certainly improved. We tested against a list of file ids from our blob
store and I can't find that list right now. I'll take a look at the history
in the internal repository to see if I can find it.

I looked at the 7 image files in
https://github.com/rainycape/magick/tree/master/test_data, and Go's
decoders only failed on optimized.gif, in the LZW code, and I note
that you said that GraphicsMagick also fails to decode this.
It does not fail on that one, but on others more "optimized" IIRC.

Want to resize an image? Write your own algorithm!
There are many different resizing algorithms and approaches. I would
imagine that pure Go image resizing can and should be done by a "go
get"table third party library. Not everything has to be in the
standard library.

I totally agree, resizing algorithms should be pluggable. However, I think
the standard library should provide a basic framework for them, so users
could write only the code for the interpolation.


type Interpolator interface... or type Interpolator func... for better

func Resize(im Image, width, height int, inter Interpolator) (Image, error)

Need to work with animated GIFs? Not supported!
Animated GIFs are supported, via gif.DecodeAll. It's true that
image.Decode will only give you the first frame, but the image
package's format.go is trivial to fork if you really need a catch-all
decoder that can give you Image or *GIF (or []Image).
Everything is trivial given enough time. The problem with gif.DecodeAll is
that you have to either special case when image.Decode returns a GIF, to
decode the images again (and, according to the code, all of them they were
previously decoded, but thrown away, so you're doing 2x the required work)
or either read the image bytes into a buffer, check the magic number for
GIF89A and then pass a bytes.Reader to either image.Decode or
gif.DecodeAll. Then if you want to do something useful with them you need
to do the coalescing yourself, since gif.DecodeAll doesn't do that for you.
With IM or GM you have a unified interface, where you can decode an image,
resize it and then encode it using any supported format. You don't need to
care about all the details unless you're encoding to a format which
supports animation and want to only show the first frame (like e.g. when
generating a thumbnail). And even in that case, you can just call
im.Frame(0) and it will work on both animated and non-animated images.

At the end of the day, is a matter of engineering the better solution to
your problem, and for us that was wrapping ImageMagick.

At the end of the day, though, if binding ImageMagick works for you,
then don't let me stop you. :-)
I won't, don't worry ;)


You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

Discussion Posts


Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 6 of 12 | next ›
Discussion Overview
groupgolang-nuts @
postedOct 30, '13 at 4:29p
activeFeb 13, '16 at 4:14a



site design / logo © 2022 Grokbase