]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Dither colors in non-default low depth color path
authorCharlie Brej <cbrej@cs.man.ac.uk>
Mon, 27 Oct 2008 16:49:06 +0000 (12:49 -0400)
committerRay Strode <rstrode@redhat.com>
Mon, 27 Oct 2008 16:49:06 +0000 (12:49 -0400)
This patch modifies the low color mode (slow) path
to dither the colors before flushing them to the
scanout buffer.  This improves the output quality
in those corner cases.

src/libply/ply-frame-buffer.c

index d80a6cdbcbb2a98f1fb8bbee582ba9b878161c5e..dd26646962ad823a307d3d9c5864438ebfaf16df 100644 (file)
@@ -68,6 +68,10 @@ struct _ply_frame_buffer
   uint32_t bits_for_blue;
   uint32_t bits_for_alpha;
 
+  int32_t dither_red;
+  int32_t dither_green;
+  int32_t dither_blue;
+
   unsigned int bytes_per_pixel;
   unsigned int row_stride;
 
@@ -315,6 +319,10 @@ ply_frame_buffer_query_device (ply_frame_buffer_t *buffer)
   buffer->bytes_per_pixel = variable_screen_info.bits_per_pixel >> 3;
   buffer->row_stride = fixed_screen_info.line_length / buffer->bytes_per_pixel;
   buffer->size = buffer->area.height * buffer->row_stride * buffer->bytes_per_pixel;
+  
+  buffer->dither_red = 0;
+  buffer->dither_green = 0;
+  buffer->dither_blue = 0;
 
   if (buffer->bytes_per_pixel == 4 &&
       buffer->red_bit_position == 16 && buffer->bits_for_red == 8 &&
@@ -340,24 +348,37 @@ ply_frame_buffer_map_to_device (ply_frame_buffer_t *buffer)
   return buffer->map_address != MAP_FAILED;
 }
 
-__attribute__((__pure__))
 static inline uint_fast32_t 
 ply_frame_buffer_pixel_value_to_device_pixel_value (ply_frame_buffer_t *buffer,
                                                     uint32_t        pixel_value)
 {
   uint8_t r, g, b, a;
+  int orig_r, orig_g, orig_b, orig_a;
+  int i;
+  
+  orig_a = pixel_value >> 24; 
+  a = orig_a >> (8 - buffer->bits_for_alpha);
 
-  a = pixel_value >> 24; 
-  a >>= (8 - buffer->bits_for_alpha);
-
-  r = (pixel_value >> 16) & 0xff; 
-  r >>= (8 - buffer->bits_for_red);
+  orig_r = ((pixel_value >> 16) & 0xff) - buffer->dither_red; 
+  r = CLAMP(orig_r, 0, 255) >> (8 - buffer->bits_for_red);
 
-  g = (pixel_value >> 8) & 0xff; 
-  g >>= (8 - buffer->bits_for_green);
+  orig_g = ((pixel_value >> 8) & 0xff) - buffer->dither_green;
+  g = CLAMP(orig_g, 0, 255) >> (8 - buffer->bits_for_green);
 
-  b = pixel_value & 0xff; 
-  b >>= (8 - buffer->bits_for_blue);
+  orig_b = (pixel_value & 0xff) - buffer->dither_blue;
+  b = CLAMP(orig_b, 0, 255) >> (8 - buffer->bits_for_blue);
+  
+  uint8_t new_r = r << (8 - buffer->bits_for_red);
+  uint8_t new_g = g << (8 - buffer->bits_for_green);
+  uint8_t new_b = b << (8 - buffer->bits_for_blue);
+  for (i=buffer->bits_for_red;   i<8; i*=2) new_r |= new_r >> i;
+  for (i=buffer->bits_for_green; i<8; i*=2) new_g |= new_g >> i;
+  for (i=buffer->bits_for_blue;  i<8; i*=2) new_b |= new_b >> i;
+  
+  buffer->dither_red = new_r - orig_r;
+  buffer->dither_green = new_g - orig_g;
+  buffer->dither_blue = new_b - orig_b;
+  
 
   return ((a << buffer->alpha_bit_position)
           | (r << buffer->red_bit_position)