]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Thu, 10 Feb 2011 19:57:21 +0000 (19:57 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Thu, 10 Feb 2011 19:57:21 +0000 (19:57 +0000)
ChangeLog
magick/image.c
magick/quantize.c
magick/transform.c
wand/stream.c

index 4b1151851475c3cac6a8f15fcad8a95573b5113a..0538e1ce3830e5e2041b7fe49fa1b8818ef59f2a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,7 @@
   * Fix off-by-one error in PosterizeImage().
   * Posterize now distributes color uniformally (reference
     http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=17623).
-  * Add -smush option (doesn't work yet) (reference
+  * Add -smush option (reference
     http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=17953).
 
 2011-02-07  6.6.7-6 Cristy  <quetzlzacatenango@image...>
index bc6c62807029efee5831418fe414014635bf70b6..4b827814dd3e4b57ce6ef13f027626f58e81b919 100644 (file)
@@ -3831,14 +3831,138 @@ MagickExport VirtualPixelMethod SetImageVirtualPixelMethod(const Image *image,
 %
 */
 
-static ssize_t SmushXOffset(const Image *images,ExceptionInfo *exception)
+static size_t SmushXOffset(const Image *smush_image,const Image *images,
+  ExceptionInfo *exception)
 {
-  return(0);
+  CacheView
+    *left_view,
+    *right_view;
+
+  const Image
+    *left_image,
+    *right_image;
+
+  MagickBooleanType
+    status;
+
+  PixelPacket
+    pixel;
+
+  RectangleInfo
+    left_geometry,
+    right_geometry;
+
+  register ssize_t
+    y;
+
+  size_t
+    minimum_offset;
+
+  ssize_t
+    offset,
+    x;
+
+  if (images->previous == (Image *) NULL)
+    return(0);
+  right_image=images;
+  SetGeometry(smush_image,&right_geometry);
+  GravityAdjustGeometry(right_image->columns,right_image->rows,
+    right_image->gravity,&right_geometry);
+  left_image=images->previous;
+  SetGeometry(smush_image,&left_geometry);
+  GravityAdjustGeometry(left_image->columns,left_image->rows,
+    left_image->gravity,&left_geometry);
+  minimum_offset=right_image->rows;
+  left_view=AcquireCacheView(left_image);
+  right_view=AcquireCacheView(right_image);
+  for (y=0; y < (ssize_t) smush_image->rows; y++)
+  {
+    for (x=(ssize_t) left_image->columns-1; x > 0; x--)
+    {
+      status=GetOneCacheViewVirtualPixel(left_view,x,y,&pixel,exception);
+      if (pixel.opacity != TransparentOpacity)
+        break;
+    }
+    offset=(ssize_t) left_image->columns-x-1;
+    for (x=0; x < (ssize_t) right_image->columns; x++)
+    {
+      status=GetOneCacheViewVirtualPixel(right_view,x,y,&pixel,exception);
+      if (pixel.opacity != TransparentOpacity)
+        break;
+    }
+    if ((size_t) (x+offset) < minimum_offset)
+      minimum_offset=(size_t) (x+offset);
+  }
+  right_view=DestroyCacheView(right_view);
+  left_view=DestroyCacheView(left_view);
+  return(minimum_offset);
 }
 
-static ssize_t SmushYOffset(const Image *images,ExceptionInfo *exception)
+static size_t SmushYOffset(const Image *smush_image,const Image *images,
+  ExceptionInfo *exception)
 {
-  return(0);
+  CacheView
+    *bottom_view,
+    *top_view;
+
+  const Image
+    *bottom_image,
+    *top_image;
+
+  MagickBooleanType
+    status;
+
+  PixelPacket
+    pixel;
+
+  RectangleInfo
+    bottom_geometry,
+    top_geometry;
+
+  register ssize_t
+    x;
+
+  size_t
+    minimum_offset;
+
+  ssize_t
+    offset,
+    y;
+
+  if (images->previous == (Image *) NULL)
+    return(0);
+  bottom_image=images;
+  SetGeometry(smush_image,&bottom_geometry);
+  GravityAdjustGeometry(bottom_image->columns,bottom_image->rows,
+    bottom_image->gravity,&bottom_geometry);
+  top_image=images->previous;
+  SetGeometry(smush_image,&top_geometry);
+  GravityAdjustGeometry(top_image->columns,top_image->rows,top_image->gravity,
+    &top_geometry);
+  minimum_offset=bottom_image->rows;
+  top_view=AcquireCacheView(top_image);
+  bottom_view=AcquireCacheView(bottom_image);
+  for (x=0; x < (ssize_t) smush_image->columns; x++)
+  {
+    for (y=(ssize_t) top_image->rows-1; y > 0; y--)
+    {
+      status=GetOneCacheViewVirtualPixel(top_view,x,y,&pixel,exception);
+      if (pixel.opacity != TransparentOpacity)
+        break;
+    }
+    offset=(ssize_t) top_image->rows-y-1;
+    for (y=0; y < (ssize_t) bottom_image->rows; y++)
+    {
+      status=GetOneCacheViewVirtualPixel(bottom_view,x,y,&pixel,exception);
+      if (pixel.opacity != TransparentOpacity)
+        break;
+    }
+    if ((size_t) (y+offset) < minimum_offset)
+      minimum_offset=(size_t) (y+offset);
+  }
+  bottom_view=DestroyCacheView(bottom_view);
+  top_view=DestroyCacheView(top_view);
+  return(minimum_offset);
 }
 
 MagickExport Image *SmushImages(const Image *images,
@@ -3892,6 +4016,10 @@ MagickExport Image *SmushImages(const Image *images,
   number_images=1;
   width=image->columns;
   height=image->rows;
+  if (stack != MagickFalse)
+    width+=GetImageListLength(image)*offset;
+  else
+    height+=GetImageListLength(image)*offset;
   next=GetNextImageInList(image);
   for ( ; next != (Image *) NULL; next=GetNextImageInList(next))
   {
@@ -3934,12 +4062,12 @@ MagickExport Image *SmushImages(const Image *images,
     if (stack != MagickFalse)
       {
         x_offset-=geometry.x;
-        x_offset-=SmushXOffset(image,exception)+offset;
+        y_offset-=SmushYOffset(smush_image,image,exception)-offset;
       }
     else
       {
+        x_offset-=SmushXOffset(smush_image,image,exception)-offset;
         y_offset-=geometry.y;
-        y_offset-=SmushYOffset(image,exception)+offset;
       }
     status=CompositeImage(smush_image,OverCompositeOp,image,x_offset,y_offset);
     proceed=SetImageProgress(image,SmushImageTag,n,number_images);
@@ -3958,6 +4086,10 @@ MagickExport Image *SmushImages(const Image *images,
     image=GetNextImageInList(image);
   }
   smush_view=DestroyCacheView(smush_view);
+  if (stack != MagickFalse)
+    status=SetImageExtent(smush_image,smush_image->columns,(size_t) y_offset);
+  else
+    status=SetImageExtent(smush_image,(size_t) x_offset,smush_image->rows);
   if (status == MagickFalse)
     smush_image=DestroyImage(smush_image);
   return(smush_image);
index 759831f8420344f45d8c13189db7efbaf5b2610d..f12004a51dd8cbcb85c228d346ff7a2c2d98a3af 100644 (file)
@@ -2180,6 +2180,16 @@ MagickExport void GetQuantizeInfo(QuantizeInfo *quantize_info)
 %
 */
 
+static inline ssize_t MagickRound(MagickRealType x)
+{
+  /*
+   Round the fraction to nearest integer.
+  */
+  if (x >= 0.0)
+    return((ssize_t) (x+0.5));
+  return((ssize_t) (x-0.5));
+}
+
 MagickExport MagickBooleanType PosterizeImage(Image *image,const size_t levels,
   const MagickBooleanType dither)
 {
@@ -2194,10 +2204,8 @@ MagickExport MagickBooleanType PosterizeImageChannel(Image *image,
   const ChannelType channel,const size_t levels,const MagickBooleanType dither)
 {
 #define PosterizeImageTag  "Posterize/Image"
-#define PosterizePixel(pixel) (Quantum) (QuantumRange*(PosterizeRound( \
+#define PosterizePixel(pixel) (Quantum) (QuantumRange*(MagickRound( \
   QuantumScale*pixel*(levels-1))/(levels-1)))
-#define PosterizeRound(pixel) ((pixel) < 0.0 ? -floor((double) \
-  (-(pixel)+0.5)) : floor((double) (pixel)+0.5))
 
   CacheView
     *image_view;
index 1c47e894fea954105e899eeef5447a8bb7355873..99dfbc693e722fc14d9f1ddda5f33f74d36f7b78 100644 (file)
@@ -1709,6 +1709,7 @@ MagickExport Image *SpliceImage(const Image *image,
 %      final size of the image.
 %
 */
+
 static inline ssize_t MagickRound(MagickRealType x)
 {
   /*
index e0d5f0709b2e61f0f30473dec9ae5a28acd35df8..ca16b1a1ea1bd7b90fd291cbad3be81fc19f8a42 100644 (file)
@@ -81,7 +81,6 @@
 %
 %    o exception: return any errors or warnings in this structure.
 %
-%
 */
 
 static MagickBooleanType StreamUsage(void)