RMagick reacts very oddly to an incorrect file

P

Pito Salas

I am not sure if this is me or Rmagick. I 'accidentally' used an input
file which was a 40Meg multi-image TIF with 50 or so images and my mac
os x went totally haywire. As I traced down into the problem I got to
this:

# Initialize new instances
def initialize(*filenames, &block)
@images = []
@scene = nil
filenames.each { |f|
Magick::Image.read(f, &block).each { |n| @images << n }
}
if length > 0
@scene = length - 1 # last image in array
end
self
end

Which is near line 1600 of RMagick.rb. And in particular, the line

Magick::Image.read(f, &block).each { |n| @images << n }

Is where things go sour. My disk whirls like crazy, my mac becomes
totally unresponsive and eventually I figured out that I could locate a
particular process running ruby and kill it surgically and after a few
moments things settled back to normal.

Odder still, if I stepped into the Image.read I found the particular
call was to @path.dup where things went sour. @path at that moment
seemed to have an innocuous string in it.

I assume this is sufficiently arcane that only one person on this list
will have a comment... But if anyone, especially TimH can shed some
light I would appreciate it!

I want to put some defensive code into my stuff but I am not sure what I
am checking for. Is it just a very large file or what?

Thanks!!

Pito
 
T

Tim Hunter

Pito said:
I am not sure if this is me or Rmagick. I 'accidentally' used an input
file which was a 40Meg multi-image TIF with 50 or so images and my mac
os x went totally haywire. As I traced down into the problem I got to
this:

# Initialize new instances
def initialize(*filenames, &block)
@images = []
@scene = nil
filenames.each { |f|
Magick::Image.read(f, &block).each { |n| @images << n }
}
if length > 0
@scene = length - 1 # last image in array
end
self
end

Which is near line 1600 of RMagick.rb. And in particular, the line

Magick::Image.read(f, &block).each { |n| @images << n }

Is where things go sour. My disk whirls like crazy, my mac becomes
totally unresponsive and eventually I figured out that I could locate a
particular process running ruby and kill it surgically and after a few
moments things settled back to normal.

Odder still, if I stepped into the Image.read I found the particular
call was to @path.dup where things went sour. @path at that moment
seemed to have an innocuous string in it.

I assume this is sufficiently arcane that only one person on this list
will have a comment... But if anyone, especially TimH can shed some
light I would appreciate it!

I want to put some defensive code into my stuff but I am not sure what I
am checking for. Is it just a very large file or what?

Thanks!!

Pito

My guess is that you ran out of memory and OS X started swapping to
disk. This would explain your disk whirling and your computer getting
unresponsive. Killing the process freed the memory and things went back
to normal.
 
P

Pito Salas

Tim said:
My guess is that you ran out of memory and OS X started swapping to
disk. This would explain your disk whirling and your computer getting
unresponsive. Killing the process freed the memory and things went back
to normal.

But why would a 40M file run out of memory on a machine with 2G of
memory, and why didn't it just throw an error? By the way if I use
ImageMagick itself, off the command line with the identify command it
has no problem with the file.
 
T

Tim Hunter

Pito said:
But why would a 40M file run out of memory on a machine with 2G of
memory, and why didn't it just throw an error? By the way if I use
ImageMagick itself, off the command line with the identify command it
has no problem with the file.

Without the file I can only guess. It didn't throw an error because it
hadn't encountered an error yet. RMagick doesn't report an error until
ImageMagick reports an error, and if OS X is still swapping stuff out to
disk trying to allocate memory ImageMagick hasn't failed yet.

Why would a 40M file use up a lot of memory? Thanks to compression the
file size on disk doesn't have a lot to do with how big the image is in
memory. What quantum depth is ImageMagick configured to use? You can
find out by running this command:

convert -version

It'll say either Q8 or Q16. Most people are using Q16. If you are, then
ImageMagick uses 2 bytes for each of the R, G, B, and A channels, or 8
bytes per pixel, plus about 1 byte per pixel overhead. So figure 9*W*H
bytes per image in the file, where W is the width in pixels and H is the
height. You said this file had about 50 images in it. You didn't say how
big the images are, but you can do the arithmetic.

Why would identify work? Identify doesn't need to keep the entire image
in memory.

If you want to put in some defensive code, check out the
Magick.limit_resource method:
http://studio.imagemagick.org/RMagick/doc/magick.html#limit_resource.

But all this is just my best guess. If you want me to analyze your
specific image open a support request on RubyForge and attach the file.
Also tell me the version of ImageMagick and the version of RMagick
you're using.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top