Bug 686954 Rowstride issue on display device

"Russell Lang" <[email protected]> Sat, 21 Aug 2004 20:34:00 +1000
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <4127B1B8.28581.2E9C7068@localhost>
Log Message:
Allow the display device row alignment to be changed from the
default 4 bytes to 8, 16, 32 or 64 bytes.

DETAILS:
If the image is allocated in video display memory, an alignment
such as 16 bytes (128-bit memory) may be required.
This is implemented by making the underlying memory device
use a larger width than the display device.

Russell Lang                   [email protected]
Ghostgum Software Pty Ltd      http://www.ghostgum.com.au/

diff -u l:/cvs/gs/src/gdevdsp.c src/gdevdsp.c
--- l:/cvs/gs/src/gdevdsp.c	Fri Aug 06 23:01:55 2004
+++ src/gdevdsp.c	Sat Aug 21 10:15:20 2004
@@ -226,6 +226,7 @@
 private int display_alloc_bitmap(gx_device_display *, gx_device *);
 private int display_set_color_format(gx_device_display *dev, int nFormat);
 private int display_set_separations(gx_device_display *dev);
+private int display_raster(gx_device_display *dev);
 
 /* Open the display driver. */
 private int
@@ -260,7 +261,7 @@
 
     /* Tell caller the proposed device parameters */
     ccode = (*(ddev->callback->display_presize)) (ddev->pHandle, dev,
-	dev->width, dev->height, gdev_mem_raster(dev), ddev->nFormat);
+	dev->width, dev->height, display_raster(ddev), ddev->nFormat);
     if (ccode < 0) {
 	(*(ddev->callback->display_close))(ddev->pHandle, dev);
 	return_error(ccode);
@@ -275,7 +276,7 @@
 
     /* Tell caller the device parameters */
     ccode = (*(ddev->callback->display_size)) (ddev->pHandle, dev,
-	dev->width, dev->height, gdev_mem_raster(dev), ddev->nFormat, 
+	dev->width, dev->height, display_raster(ddev), ddev->nFormat, 
 	ddev->mdev->base);
     if (ccode < 0) {
 	display_free_bitmap(ddev);
@@ -892,7 +893,7 @@
 	 */
 	/* Tell caller we are about to change the device parameters */
 	if ((*ddev->callback->display_presize)(ddev->pHandle, dev,
-	    dev->width, dev->height, gdev_mem_raster(dev),
+	    dev->width, dev->height, display_raster(ddev),
 	    ddev->nFormat) < 0) {
 	    /* caller won't let us change the size */
 	    /* restore parameters then return an error */
@@ -918,7 +919,7 @@
     
 	/* tell caller about the new size */
 	if ((*ddev->callback->display_size)(ddev->pHandle, dev, 
-	    dev->width, dev->height, gdev_mem_raster(dev),
+	    dev->width, dev->height, display_raster(ddev),
 	    ddev->nFormat, ddev->mdev->base) < 0)
 	    return_error(gs_error_rangecheck);
     }
@@ -1146,6 +1147,34 @@
     }
 }
 
+/* calculate byte length of a row */
+private int 
+display_raster(gx_device_display *dev)
+{
+    int align = 4;
+    int bytewidth = dev->width * dev->color_info.depth/8;
+    switch (dev->nFormat & DISPLAY_ROW_ALIGN_MASK) {
+	case DISPLAY_ROW_ALIGN_4:
+	    align = 4;
+	    break;
+	case DISPLAY_ROW_ALIGN_8:
+	    align = 8;
+	    break;
+	case DISPLAY_ROW_ALIGN_16:
+	    align = 16;
+	    break;
+	case DISPLAY_ROW_ALIGN_32:
+	    align = 32;
+	    break;
+	case DISPLAY_ROW_ALIGN_64:
+	    align = 64;
+	    break;
+    }
+    align -= 1;
+    bytewidth = (bytewidth + align) & (~align);
+    return bytewidth;
+}
+
 /* Allocate the backing bitmap. */
 private int
 display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
@@ -1177,8 +1206,13 @@
      */
     gx_device_retain((gx_device *)(ddev->mdev), true);
     
+    /* Memory device width may be larger than device width
+     * if row alignment is not 4.
+     */
     ddev->mdev->width = param_dev->width;
+    ddev->mdev->width = display_raster(ddev) * 8 / ddev->color_info.depth;
     ddev->mdev->height = param_dev->height;
+
     /* Tell the memory device to allocate the line pointers separately
      * so we can place the bitmap in special memory.
      */
@@ -1633,7 +1667,16 @@
      DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
     {"32bit/pixel CMYK, bottom first",
      DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
-     DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST}
+     DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
+    {"64bit/pixel separations, bottom first",
+     DISPLAY_COLORS_SEPARATIONS | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
+     DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
+    {"1bit/pixel native, black is 1, 8 byte alignment",
+     DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 | 
+     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_8},
+    {"24bit/pixel color, bottom first, BGR24, 64 byte alignment",
+     DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
+     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_ROW_ALIGN_64}
 };
 
 void
diff -u l:/cvs/gs/src/gdevdsp.h src/gdevdsp.h
--- l:/cvs/gs/src/gdevdsp.h	Wed Jul 07 09:33:19 2004
+++ src/gdevdsp.h	Sat Aug 21 10:19:29 2004
@@ -128,6 +128,22 @@
 } DISPLAY_FORMAT_555;
 #define DISPLAY_555_MASK 0x00040000L
 
+/* Define the row alignment.  The default is 4 bytes, so 
+ * DISPLAY_ROW_ALIGN_DEFAULT is the same as DISPLAY_ROW_ALIGN_4
+ */
+typedef enum {
+    DISPLAY_ROW_ALIGN_DEFAULT = (0<<20),
+    /* DISPLAY_ROW_ALIGN_1 = (1<<20), */ /* not currently possible */
+    /* DISPLAY_ROW_ALIGN_2 = (2<<20), */ /* not currently possible */
+    DISPLAY_ROW_ALIGN_4 = (3<<20),
+    DISPLAY_ROW_ALIGN_8 = (4<<20),
+    DISPLAY_ROW_ALIGN_16 = (5<<20),
+    DISPLAY_ROW_ALIGN_32 = (6<<20),
+    DISPLAY_ROW_ALIGN_64 = (7<<20)
+} DISPLAY_FORMAT_ROW_ALIGN;
+#define DISPLAY_ROW_ALIGN_MASK 0x00700000L
+
+
 #ifndef display_callback_DEFINED
 #define display_callback_DEFINED
 typedef struct display_callback_s display_callback;

_______________________________________________
gs-code-review mailing list
[email protected]
http://www.ghostscript.com/mailman/listinfo/gs-code-review