<p dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>></p>
<div class="gmail_quote">On Feb 13, 2015 3:56 AM, "Iago Toral Quiroga" <<a href="mailto:itoral@igalia.com">itoral@igalia.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Some old format conversion code in pack.c implemented byte-swapping like this:<br>
<br>
GLint comps = _mesa_components_in_format(dstFormat);<br>
GLint swapSize = _mesa_sizeof_packed_type(dstType);<br>
if (swapSize == 2)<br>
   _mesa_swap2((GLushort *) dstAddr, n * comps);<br>
else if (swapSize == 4)<br>
   _mesa_swap4((GLuint *) dstAddr, n * comps);<br>
<br>
where n is the pixel count. But this is incorrect for packed formats,<br>
where _mesa_sizeof_packed_type is already returning the size of a pixel<br>
instead of the size of a single component, so multiplying this by the<br>
number of components in the format results in a larger element count<br>
for _mesa_swap than we want.<br>
<br>
Unfortunately, we followed the same implementation for byte-swapping<br>
in the rewrite of the format conversion code for texstore, readpixels<br>
and texgetimage.<br>
<br>
This patch computes the correct element counts for _mesa_swap calls<br>
by computing the bytes per pixel in the image and dividing that by the<br>
swap size to obtain the number of swaps required per pixel. Then multiplies<br>
that by the number of pixels in the image to obtain the swap count that<br>
we need to use.<br>
<br>
Also, when handling byte-swapping in texstore_rgba, we were ignoring<br>
the image's depth. This patch fixes this too.<br>
---<br>
 src/mesa/main/readpix.c     | 13 ++++++++-----<br>
 src/mesa/main/texgetimage.c | 13 ++++++++-----<br>
 src/mesa/main/texstore.c    | 14 +++++++++-----<br>
 3 files changed, 25 insertions(+), 15 deletions(-)<br>
<br>
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c<br>
index 85f900d..ca4b943 100644<br>
--- a/src/mesa/main/readpix.c<br>
+++ b/src/mesa/main/readpix.c<br>
@@ -605,12 +605,15 @@ read_rgba_pixels( struct gl_context *ctx,<br>
 done_swap:<br>
    /* Handle byte swapping if required */<br>
    if (packing->SwapBytes) {<br>
-      int components = _mesa_components_in_format(format);<br>
       GLint swapSize = _mesa_sizeof_packed_type(type);<br>
-      if (swapSize == 2)<br>
-         _mesa_swap2((GLushort *) dst, width * height * components);<br>
-      else if (swapSize == 4)<br>
-         _mesa_swap4((GLuint *) dst, width * height * components);<br>
+      if (swapSize == 2 || swapSize == 4) {<br>
+         int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize;<br>
+         assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0);<br>
+         if (swapSize == 2)<br>
+            _mesa_swap2((GLushort *) dst, width * height * swapsPerPixel);<br>
+         else if (swapSize == 4)<br>
+            _mesa_swap4((GLuint *) dst, width * height * swapsPerPixel);<br>
+      }<br>
    }<br>
<br>
 done_unmap:<br>
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c<br>
index ee465e6..405f085 100644<br>
--- a/src/mesa/main/texgetimage.c<br>
+++ b/src/mesa/main/texgetimage.c<br>
@@ -511,12 +511,15 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,<br>
    do_swap:<br>
       /* Handle byte swapping if required */<br>
       if (ctx->Pack.SwapBytes) {<br>
-         int components = _mesa_components_in_format(format);<br>
          GLint swapSize = _mesa_sizeof_packed_type(type);<br>
-         if (swapSize == 2)<br>
-            _mesa_swap2((GLushort *) dest, width * height * components);<br>
-         else if (swapSize == 4)<br>
-            _mesa_swap4((GLuint *) dest, width * height * components);<br>
+         if (swapSize == 2 || swapSize == 4) {<br>
+            int swapsPerPixel = _mesa_bytes_per_pixel(format, type) / swapSize;<br>
+            assert(_mesa_bytes_per_pixel(format, type) % swapSize == 0);<br>
+            if (swapSize == 2)<br>
+               _mesa_swap2((GLushort *) dest, width * height * swapsPerPixel);<br>
+            else if (swapSize == 4)<br>
+               _mesa_swap4((GLuint *) dest, width * height * swapsPerPixel);<br>
+         }<br>
       }<br>
<br>
       /* Unmap the src texture buffer */<br>
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c<br>
index 4d32659..227693d 100644<br>
--- a/src/mesa/main/texstore.c<br>
+++ b/src/mesa/main/texstore.c<br>
@@ -721,15 +721,19 @@ texstore_rgba(TEXSTORE_PARAMS)<br>
        */<br>
       GLint swapSize = _mesa_sizeof_packed_type(srcType);<br>
       if (swapSize == 2 || swapSize == 4) {<br>
-         int components = _mesa_components_in_format(srcFormat);<br>
-         int elementCount = srcWidth * srcHeight * components;<br>
-         tempImage = malloc(elementCount * swapSize);<br>
+         int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType);<br>
+         assert(bytesPerPixel % swapSize == 0);<br>
+         int swapsPerPixel = bytesPerPixel / swapSize;<br>
+         int elementCount = srcWidth * srcHeight * srcDepth;<br>
+         tempImage = malloc(elementCount * bytesPerPixel);<br>
          if (!tempImage)<br>
             return GL_FALSE;<br>
          if (swapSize == 2)<br>
-            _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);<br>
+            _mesa_swap2_copy(tempImage, (GLushort *) srcAddr,<br>
+                             elementCount * swapsPerPixel);<br>
          else<br>
-            _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);<br>
+            _mesa_swap4_copy(tempImage, (GLuint *) srcAddr,<br>
+                             elementCount * swapsPerPixel);<br>
          srcAddr = tempImage;<br>
       }<br>
    }<br>
--<br>
1.9.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div>