Revision: 2014
          http://gtkpod.svn.sourceforge.net/gtkpod/?rev=2014&view=rev
Author:   teuf
Date:     2008-06-09 13:08:08 -0700 (Mon, 09 Jun 2008)

Log Message:
-----------
* src/itdb_device.h:
* src/itdb_sysinfo_extended_parser.c:
* src/ithumb-writer.c: use background color and alignement
information from SysInfoExtended if available

Modified Paths:
--------------
    libgpod/trunk/ChangeLog
    libgpod/trunk/src/itdb_device.h
    libgpod/trunk/src/itdb_sysinfo_extended_parser.c
    libgpod/trunk/src/ithumb-writer.c

Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog     2008-06-09 20:04:23 UTC (rev 2013)
+++ libgpod/trunk/ChangeLog     2008-06-09 20:08:08 UTC (rev 2014)
@@ -1,4 +1,3 @@
-
 2008-06-09  Christophe Fergeau  <[EMAIL PROTECTED]>
 
        * src/itdb_device.h:

Modified: libgpod/trunk/src/itdb_device.h
===================================================================
--- libgpod/trunk/src/itdb_device.h     2008-06-09 20:04:23 UTC (rev 2013)
+++ libgpod/trunk/src/itdb_device.h     2008-06-09 20:08:08 UTC (rev 2014)
@@ -95,20 +95,20 @@
 };
 
 struct _Itdb_ArtworkFormat {
-        gint16 format_id; 
-        gint16 width; 
-        gint16 height; 
-        ItdbThumbFormat format; 
+        gint16 format_id;
+        gint16 width;
+        gint16 height;
+        ItdbThumbFormat format;
         gint32 padding; /* not found in SysInfoExtended, added  
                          * for compatibility with hardcoded artwork formats */ 
-        gboolean crop; 
-        gint rotation; 
-        guint back_color; 
+        gboolean crop;
+        gint rotation;
+        guchar back_color[4];
  
-        gint display_width; 
-        gboolean interlaced; 
-        gboolean align_row_bytes; 
-        gint color_adjustment; 
+        gint display_width;
+        gboolean interlaced;
+        gboolean align_row_bytes;
+        gint color_adjustment;
         gdouble gamma;
         gint associated_format;
 };

Modified: libgpod/trunk/src/itdb_sysinfo_extended_parser.c
===================================================================
--- libgpod/trunk/src/itdb_sysinfo_extended_parser.c    2008-06-09 20:04:23 UTC 
(rev 2013)
+++ libgpod/trunk/src/itdb_sysinfo_extended_parser.c    2008-06-09 20:08:08 UTC 
(rev 2014)
@@ -407,16 +407,22 @@
 
 static void set_back_color (Itdb_ArtworkFormat *img_spec, GHashTable *dict)
 {
-        char *back_color;
-        
-        img_spec->back_color = 0;
-        back_color = get_string (dict, "BackColor");
-        if (back_color == NULL) {
-            return;
-        }
-        img_spec->back_color = strtoul (back_color, NULL, 16);
-        g_hash_table_remove (dict, "BackColor");
-        g_free (back_color);
+    char *back_color_str;
+    guint back_color;
+    gchar i;
+
+    memset (img_spec->back_color, 0, sizeof (img_spec->back_color));;
+    back_color_str = get_string (dict, "BackColor");
+    if (back_color_str == NULL) {
+        return;
+    }
+    back_color = strtoul (back_color_str, NULL, 16);
+    for (i = 3; i >= 0; i--) {
+        img_spec->back_color[(guchar)i] = back_color & 0xff;
+        back_color = back_color >> 8;
+    }
+    g_hash_table_remove (dict, "BackColor");
+    g_free (back_color_str);
 }
 
 static Itdb_ArtworkFormat *g_value_to_image_format (GValue *value)
@@ -550,7 +556,7 @@
 G_GNUC_INTERNAL gboolean
 itdb_sysinfo_properties_supports_sparse_artwork (const SysInfoIpodProperties 
*props)
 {
-    g_return_val_if_fail (props != NULL, NULL);
+    g_return_val_if_fail (props != NULL, FALSE);
 
     return props->supports_sparse_artwork;
 }

Modified: libgpod/trunk/src/ithumb-writer.c
===================================================================
--- libgpod/trunk/src/ithumb-writer.c   2008-06-09 20:04:23 UTC (rev 2013)
+++ libgpod/trunk/src/ithumb-writer.c   2008-06-09 20:08:08 UTC (rev 2014)
@@ -68,6 +68,26 @@
 typedef struct _iThumbWriter iThumbWriter;
 
 
+static guint16 get_RGB_565_pixel (const guchar *pixel, gint byte_order)
+{
+    gint r;
+    gint g;
+    gint b;
+
+    r = pixel[0];
+    g = pixel[1];
+    b = pixel[2];
+
+    r >>= (8 - RED_BITS_565);
+    g >>= (8 - GREEN_BITS_565);
+    b >>= (8 - BLUE_BITS_565);
+    r = (r << RED_SHIFT_565) & RED_MASK_565;
+    g = (g << GREEN_SHIFT_565) & GREEN_MASK_565;
+    b = (b << BLUE_SHIFT_565) & BLUE_MASK_565;
+
+    return get_gint16 (r | g | b, byte_order);
+}
+
 static guint16 *
 pack_RGB_565 (GdkPixbuf *pixbuf, const Itdb_ArtworkFormat *img_info,
              gint horizontal_padding, gint vertical_padding,
@@ -79,48 +99,100 @@
        gint channels;
        gint width;
        gint height;
-       gint w;
        gint h;
        gint byte_order;
+        gint dest_width;
 
        g_object_get (G_OBJECT (pixbuf), 
                      "rowstride", &row_stride, "n-channels", &channels,
                      "height", &height, "width", &width,
                      "pixels", &pixels, NULL);
        g_return_val_if_fail ((width <= img_info->width) && (height <= 
img_info->height), NULL);
+
+        if ((img_info->align_row_bytes) && ((img_info->width % 2) != 0)) {
+            /* each pixel is 2 bytes, to align rows on 4 bytes boundaries,
+             * width must be a multiple of 2 */
+            dest_width = img_info->width + 1;
+        } else {
+            dest_width = img_info->width;
+        }
        /* dst_width and dst_height come from a width/height database 
         * hardcoded in libipoddevice code, so dst_width * dst_height * 2 can't
         * overflow, even on an iPod containing malicious data
         */
-       *thumb_size = img_info->width * img_info->height * 2;
+       *thumb_size = dest_width * img_info->height * 2;
        result = g_malloc0 (*thumb_size);
 
        byte_order = itdb_thumb_get_byteorder (img_info->format);
 
+        for (h = 0; h < vertical_padding; h++) {
+            gint w;
+            gint line = h * dest_width;
+
+            for (w = 0 ; w < dest_width; w++) {
+                result[line + w] = get_RGB_565_pixel (img_info->back_color, 
+                                                      byte_order);
+            }
+            line += (height+vertical_padding)*dest_width;
+            for (w = 0 ; w < dest_width; w++) {
+                result[line + w] = get_RGB_565_pixel (img_info->back_color, 
+                                                      byte_order);
+            }
+        }
+
        for (h = 0; h < height; h++) {
-               gint line = (h+vertical_padding)*img_info->width;
-               for (w = 0; w < width; w++) {
-                       gint r;
-                       gint g;
-                       gint b;
+            gint line = (h+vertical_padding)*dest_width;
+            gint w;
+            for (w = 0; w < dest_width; w++) {
+                guint16 packed_pixel;
+                if (w < horizontal_padding) {
+                    packed_pixel = get_RGB_565_pixel (img_info->back_color,
+                                                      byte_order);
+                } else if (w >= horizontal_padding+width) {
+                    packed_pixel = get_RGB_565_pixel (img_info->back_color,
+                                                      byte_order);
+                } else {
+                    guchar *cur_pixel;
 
-                       r = pixels[h*row_stride + w*channels];
-                       g = pixels[h*row_stride + w*channels + 1]; 
-                       b = pixels[h*row_stride + w*channels + 2]; 
-
-                       r >>= (8 - RED_BITS_565);
-                       g >>= (8 - GREEN_BITS_565);
-                       b >>= (8 - BLUE_BITS_565);
-                       r = (r << RED_SHIFT_565) & RED_MASK_565;
-                       g = (g << GREEN_SHIFT_565) & GREEN_MASK_565;
-                       b = (b << BLUE_SHIFT_565) & BLUE_MASK_565;
-                       result[line + w + horizontal_padding] =
-                           get_gint16 (r | g | b, byte_order);
-               }
+                    cur_pixel = &pixels[h*row_stride + w*channels];
+                    packed_pixel = get_RGB_565_pixel (cur_pixel, byte_order);
+                }
+                result[line + w] = packed_pixel;
+            }
        }
        return result;
 }
 
+static guint16 get_RGB_555_pixel (const guchar *pixel, gint byte_order, 
+                                  gboolean has_alpha)
+{
+    gint r;
+    gint g;
+    gint b;
+    gint a;
+
+    r = pixel[0];
+    g = pixel[1];
+    b = pixel[2];
+    if (has_alpha) {
+        a = pixel[3];
+    } else {
+        /* I'm not sure if the highest bit really is the alpha channel. 
+         * For now I'm just setting this bit because that's what I have seen. 
*/
+        a = 1;
+    }
+
+    r >>= (8 - RED_BITS_555);
+    g >>= (8 - GREEN_BITS_555);
+    b >>= (8 - BLUE_BITS_555);
+    r = (r << RED_SHIFT_555) & RED_MASK_555;
+    g = (g << GREEN_SHIFT_555) & GREEN_MASK_555;
+    b = (b << BLUE_SHIFT_555) & BLUE_MASK_555;
+    a = (a << ALPHA_SHIFT_555) & ALPHA_MASK_555;
+
+    return get_gint16 (a | r | g | b, byte_order);
+}
+
 static guint16 *
 pack_RGB_555 (GdkPixbuf *pixbuf, const Itdb_ArtworkFormat *img_info,
              gint horizontal_padding, gint vertical_padding,
@@ -132,55 +204,101 @@
        gint channels;
        gint width;
        gint height;
-       gint w;
        gint h;
        gint byte_order;
+        gint dest_width;
 
        g_object_get (G_OBJECT (pixbuf), 
                      "rowstride", &row_stride, "n-channels", &channels,
                      "height", &height, "width", &width,
                      "pixels", &pixels, NULL);
        g_return_val_if_fail ((width <= img_info->width) && (height <= 
img_info->height), NULL);
+
+        if ((img_info->align_row_bytes) && ((img_info->width % 2) != 0)) {
+            /* each pixel is 2 bytes, to align rows on 4 bytes boundaries,
+             * width must be a multiple of 2 */
+            dest_width = img_info->width + 1;
+        } else {
+            dest_width = img_info->width;
+        }
+
        /* dst_width and dst_height come from a width/height database 
         * hardcoded in libipoddevice code, so dst_width * dst_height * 2 can't
         * overflow, even on an iPod containing malicious data
         */
-
-       *thumb_size = img_info->width * img_info->height * 2;
+       *thumb_size = dest_width * img_info->height * 2;
        result = g_malloc0 (*thumb_size);
 
        byte_order = itdb_thumb_get_byteorder (img_info->format);
 
+        for (h = 0; h < vertical_padding; h++) {
+            gint w;
+            gint line = h * dest_width;
+
+            for (w = 0 ; w < dest_width; w++) {
+                result[line + w] = get_RGB_555_pixel (img_info->back_color, 
+                                                      byte_order, TRUE);
+            }
+            line += (height+vertical_padding)*dest_width;
+            for (w = 0 ; w < dest_width; w++) {
+                result[line + w] = get_RGB_555_pixel (img_info->back_color, 
+                                                      byte_order, TRUE);
+            }
+        }
+
        for (h = 0; h < height; h++) {
-               gint line = (h+vertical_padding)*img_info->width;
-               for (w = 0; w < width; w++) {
-                       gint r;
-                       gint g;
-                       gint b;
-                       gint a;
+            gint line = (h+vertical_padding)*dest_width;
+            gint w;
+            for (w = 0; w < dest_width; w++) {
+                guint16 packed_pixel;
+                if (w < horizontal_padding) {
+                    packed_pixel = get_RGB_555_pixel (img_info->back_color,
+                                                      byte_order, TRUE);
+                } else if (w >= horizontal_padding+width) {
+                    packed_pixel = get_RGB_555_pixel (img_info->back_color,
+                                                      byte_order, TRUE);
+                } else {
+                    guchar *cur_pixel;
 
-                       r = pixels[h*row_stride + w*channels];
-                       g = pixels[h*row_stride + w*channels + 1]; 
-                       b = pixels[h*row_stride + w*channels + 2]; 
-
-                       r >>= (8 - RED_BITS_555);
-                       g >>= (8 - GREEN_BITS_555);
-                       b >>= (8 - BLUE_BITS_555);
-                       a = (1 << ALPHA_SHIFT_555) & ALPHA_MASK_555;
-                       r = (r << RED_SHIFT_555) & RED_MASK_555;
-                       g = (g << GREEN_SHIFT_555) & GREEN_MASK_555;
-                       b = (b << BLUE_SHIFT_555) & BLUE_MASK_555;
-                       result[line + w + horizontal_padding] =
-                           get_gint16 (a | r | g | b, byte_order);
-                       /* I'm not sure if the highest bit really is
-                          the alpha channel. For now I'm just setting
-                          this bit because that's what I have seen. */
-               }
+                    cur_pixel = &pixels[h*row_stride + w*channels];
+                    packed_pixel = get_RGB_555_pixel (cur_pixel, byte_order,
+                                                      FALSE);
+                }
+                result[line + w] = packed_pixel;
+            }
        }
        return result;
 }
 
+static guint16 get_RGB_888_pixel (const guchar *pixel, gint byte_order,
+                                  gboolean has_alpha)
+{
+    gint r;
+    gint g;
+    gint b;
+    gint a;
 
+    r = pixel[0];
+    g = pixel[1];
+    b = pixel[2];
+    if (has_alpha) {
+        a = pixel[3];
+    } else {
+        /* I'm not sure if the highest bit really is the alpha channel. 
+         * For now I'm just setting this bit because that's what I have seen. 
*/
+        a = 0xff; 
+    }
+    r >>= (8 - RED_BITS_888);
+    g >>= (8 - GREEN_BITS_888);
+    b >>= (8 - BLUE_BITS_888);
+    r = (r << RED_SHIFT_888) & RED_MASK_888;
+    g = (g << GREEN_SHIFT_888) & GREEN_MASK_888;
+    b = (b << BLUE_SHIFT_888) & BLUE_MASK_888;
+    a = (a << ALPHA_SHIFT_888) & ALPHA_MASK_888;
+
+    return get_gint32 (a | r | g | b, byte_order);
+}
+
 static guint16 *
 pack_RGB_888 (GdkPixbuf *pixbuf, const Itdb_ArtworkFormat *img_info,
              gint horizontal_padding, gint vertical_padding,
@@ -192,7 +310,6 @@
        gint channels;
        gint width;
        gint height;
-       gint w;
        gint h;
        gint byte_order;
 
@@ -210,31 +327,41 @@
 
        byte_order = itdb_thumb_get_byteorder (img_info->format);
 
+        for (h = 0; h < vertical_padding; h++) {
+            gint w;
+            gint line = h * img_info->width;
+
+            for (w = 0 ; w < img_info->width; w++) {
+                result[line + w] = get_RGB_888_pixel (img_info->back_color, 
+                                                      byte_order, TRUE);
+            }
+            line += (height+vertical_padding)*img_info->width;
+            for (w = 0 ; w < img_info->width; w++) {
+                result[line + w] = get_RGB_888_pixel (img_info->back_color, 
+                                                      byte_order, TRUE);
+            }
+        }
+
        for (h = 0; h < height; h++) {
-               gint line = (h+vertical_padding)*img_info->width;
-               for (w = 0; w < width; w++) {
-                       guint32 r;
-                       guint32 g;
-                       guint32 b;
-                       guint32 a;
+            gint line = (h+vertical_padding)*img_info->width;
+            gint w;
+            for (w = 0; w < img_info->width; w++) {
+                guint16 packed_pixel;
+                if (w < horizontal_padding) {
+                    packed_pixel = get_RGB_888_pixel (img_info->back_color,
+                                                      byte_order, TRUE);
+                } else if (w >= horizontal_padding+width) {
+                    packed_pixel = get_RGB_888_pixel (img_info->back_color,
+                                                      byte_order, TRUE);
+                } else {
+                    guchar *cur_pixel;
 
-                       r = pixels[h*row_stride + w*channels];
-                       g = pixels[h*row_stride + w*channels + 1]; 
-                       b = pixels[h*row_stride + w*channels + 2]; 
-
-                       r >>= (8 - RED_BITS_888);
-                       g >>= (8 - GREEN_BITS_888);
-                       b >>= (8 - BLUE_BITS_888);
-                       a = (0xff << ALPHA_SHIFT_888) & ALPHA_MASK_888;
-                       r = (r << RED_SHIFT_888) & RED_MASK_888;
-                       g = (g << GREEN_SHIFT_888) & GREEN_MASK_888;
-                       b = (b << BLUE_SHIFT_888) & BLUE_MASK_888;
-                       result[line + w + horizontal_padding] =
-                           get_gint32 (a | r | g | b, byte_order);
-                       /* I'm not sure if the highest bit really is
-                          the alpha channel. For now I'm just setting
-                          these bits because that's what I have seen. */
-               }
+                    cur_pixel = &pixels[h*row_stride + w*channels];
+                    packed_pixel = get_RGB_888_pixel (cur_pixel, byte_order,
+                                                      FALSE);
+                }
+                result[line + w] = packed_pixel;
+            }
        }
        return (guint16 *)result;
 }
@@ -291,9 +418,15 @@
 
     if (pixels)
     {
+        gint row_stride;
+        if ((img_info->align_row_bytes) && ((img_info->width % 2) != 0)) {
+            row_stride = img_info->width + 1;
+        } else {
+            row_stride = img_info->width;
+        }
        deranged_pixels = derange_pixels (NULL, pixels,
                                          img_info->width, img_info->height,
-                                         img_info->width);
+                                         row_stride);
        g_free (pixels);
     }
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to