Page 1 of 1

Wrong image size after converting eps

Posted: 2011-11-11T01:01:58-07:00
by Alex Dobusch
Hello again

...still trying to convert an eps to a jpg.

I'm using ImageMagick-6.7.3-4 and Ghostscript 9.0.4.

My eps has an image embedded with the size 551x712 at 304dpi.

With
convert "test2.eps" "test2.jpg"
the resulting jpg is an image with size 553x714, including the original 551x712 from the eps and an extra border of 2 pixel top and left.

After debugging a while I found the place where this happens: in the file 'coders\ps.c'

The eps has two size definitions
%%BoundingBox: 0 0 131 169
%%HiResBoundingBox: 0 0 130.5 168.6316

The method 'ReadPSImage' has a loop which read these definitions.
First, 'BoundingBox' will be read with

Code: Select all

    if (LocaleNCompare(BoundingBox,command,strlen(BoundingBox)) == 0)
      count=(ssize_t) sscanf(command,BoundingBox " %lf %lf %lf %lf",&bounds.x1,
        &bounds.y1,&bounds.x2,&bounds.y2);
and 'bounds' become
bounds.x1 = 0
bounds.y1 = 0
bounds.x2 = 131
bounds.y2 = 169

At Line 670, bounds will be saved in the variable 'page' and 'hires_bounds'

Code: Select all

        page.width=(size_t) floor(bounds.x2-bounds.x1+0.5);
        page.height=(size_t) floor(bounds.y2-bounds.y1+0.5);
        hires_bounds=bounds;
where 'page' become
page.width = 131
page.height = 169

In a next step 'HiResBoundingBox' will be read at Line 649 with

Code: Select all

    if (LocaleNCompare(HiResBoundingBox,command,strlen(HiResBoundingBox)) == 0)
      count=(ssize_t) sscanf(command,HiResBoundingBox " %lf %lf %lf %lf",
        &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
and 'bounds' become
bounds.x1 = 0
bounds.y1 = 0
bounds.x2 = 130.5
bounds.y2 = 168.6316

At Line 660 'bounds' is compared to 'hires_bounds'

Code: Select all

if (((bounds.x2 > hires_bounds.x2) && (bounds.y2 > hires_bounds.y2)) ||
    ((hires_bounds.x2 == 0.0) && (hires_bounds.y2 == 0.0)))
This fails, because the old 'hires_bounds' is bigger than the new 'bounds'. This means, that he definition in 'HiResBoundingBox' is lost.

At Line 735

Code: Select all

    page.width=(size_t) floor((double) (page.width*image->x_resolution/delta.x)+
      0.5);
    page.height=(size_t) floor((double) (page.height*image->y_resolution/delta.y)+
      0.5);
the page size will be recalculated with the image resolution.
page.width = floor((131*304/72)+0.5) = 553
page.height = floor((169*304/72)+0.5) = 714

This is not correct!
It should be
page.width = floor((130.5*304/72)+0.5) = 551
page.height = floor((168.6316*304/72)+0.5) = 712

After that I tried following changes:
At Line 649 replaced

Code: Select all

    if (LocaleNCompare(HiResBoundingBox,command,strlen(HiResBoundingBox)) == 0)
      count=(ssize_t) sscanf(command,HiResBoundingBox " %lf %lf %lf %lf",
        &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
with

Code: Select all

    if (LocaleNCompare(HiResBoundingBox,command,strlen(HiResBoundingBox)) == 0)
    {
      count=(ssize_t) sscanf(command,HiResBoundingBox " %lf %lf %lf %lf",
        &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
      if (count == 4)
      { // Reset hires_bounds
        hires_bounds.x2 = 0.0;
        hires_bounds.y2 = 0.0;
      }
    }
and at Line 735 replaced

Code: Select all

    page.width=(size_t) floor((double) (page.width*image->x_resolution/delta.x)+
      0.5);
    page.height=(size_t) floor((double) (page.height*image->y_resolution/delta.y)+
      0.5);
with

Code: Select all

  if (hires_bounds.x2 > 0 && hires_bounds.y2 > 0)
  {
    page.width=(size_t) floor((double)((hires_bounds.x2-hires_bounds.x1)*image->x_resolution/delta.x)+
      0.5);
    page.height=(size_t) floor((double)((hires_bounds.y2-hires_bounds.y1)*image->y_resolution/delta.y)+
      0.5);
  }
  else
  {
    page.width=(size_t) floor((double) (page.width*image->x_resolution/delta.x)+
      0.5);
    page.height=(size_t) floor((double) (page.height*image->y_resolution/delta.y)+
      0.5);
  }
With this the page size will be calculated with the definition in 'HiResBoundingBox' instead of 'BoundingBox'.

Alex

Re: Wrong image size after converting eps

Posted: 2011-11-11T06:58:06-07:00
by magick
The hi-res bounding box should be preferred over the bounding box. We'll add a patch to ImageMagick 6.7.3-6 Beta within a day or two. Thanks.

Re: Wrong image size after converting eps

Posted: 2011-11-14T00:15:21-07:00
by Alex Dobusch
Thanks
Alex

Re: Wrong image size after converting eps

Posted: 2011-11-23T08:03:41-07:00
by Alex Dobusch
Hello magick
I've looked at your changes and found the new variable 'priority', good idea.
But...
with the new variable 'priority' you prefer the hi-res bounding box, but at line 688 (in file 'coders\ps.c') you round the page-size with

Code: Select all

      page.width=(size_t) floor(hires_bounds.x2-hires_bounds.x1+0.5);
      page.height=(size_t) floor(hires_bounds.y2-hires_bounds.y1+0.5);
This means that at line 751

Code: Select all

  page.width=(size_t) floor((double) (page.width*image->x_resolution/delta.x)+
    0.5);
  page.height=(size_t) floor((double) (page.height*image->y_resolution/delta.y)+
    0.5);
the new page-size will be calculated with 'floored' values.
The resulting size is still 553x714 instead of 551x712.

Alex

Re: Wrong image size after converting eps

Posted: 2011-11-23T17:06:26-07:00
by magick
We can reproduce the problem you posted and have a patch. Look for it in the next point release of ImageMagick. Thanks.

Re: Wrong image size after converting eps

Posted: 2011-11-24T08:46:53-07:00
by Alex Dobusch
I've debugged the latest version from the subversion trunk (rev. 6074).
Now it works.

Thank You
Alex