]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Add support for DRI and RSTn markers in JPEG files.
authorSzymon Janc <szymon@janc.net.pl>
Thu, 23 Jun 2011 21:13:20 +0000 (23:13 +0200)
committerSzymon Janc <szymon@janc.net.pl>
Thu, 23 Jun 2011 21:13:20 +0000 (23:13 +0200)
* grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define.
(JPEG_MARKER_RST0): Likewise.
(JPEG_MARKER_RST1): Likewise.
(JPEG_MARKER_RST2): Likewise.
(JPEG_MARKER_RST3): Likewise.
(JPEG_MARKER_RST4): Likewise.
(JPEG_MARKER_RST5): Likewise.
(JPEG_MARKER_RST6): Likewise.
(JPEG_MARKER_RST7): Likewise.
(grub_jpeg_data): New fields dri, r1, bitmap_ptr.
(grub_jpeg_decode_dri): New function.
(grub_jpeg_decode_sos): Move image data related part into
grub_jpeg_decode_data function.
(grub_jpeg_decode_data): New function.
(grub_jpeg_reset): New function.
(grub_jpeg_decode_jpeg): Handle new markers.

ChangeLog
grub-core/video/readers/jpeg.c

index 062f66c00936b0bc9e375b682bc465b59aa6c846..655cbe25e426a3c2f62deb945e4e77b82355716d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2011-06-23  Szymon Janc <szymon@janc.net.pl>
+
+       Add support for DRI and RSTn markers in JPEG files.
+
+       * grub-core/video/readers/jpeg.c (JPEG_MARKER_DRI): New define.
+       (JPEG_MARKER_RST0): Likewise.
+       (JPEG_MARKER_RST1): Likewise.
+       (JPEG_MARKER_RST2): Likewise.
+       (JPEG_MARKER_RST3): Likewise.
+       (JPEG_MARKER_RST4): Likewise.
+       (JPEG_MARKER_RST5): Likewise.
+       (JPEG_MARKER_RST6): Likewise.
+       (JPEG_MARKER_RST7): Likewise.
+       (grub_jpeg_data): New fields dri, r1, bitmap_ptr.
+       (grub_jpeg_decode_dri): New function.
+       (grub_jpeg_decode_sos): Move image data related part into
+       grub_jpeg_decode_data function.
+       (grub_jpeg_decode_data): New function.
+       (grub_jpeg_reset): New function.
+       (grub_jpeg_decode_jpeg): Handle new markers.
+
 2011-06-23  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/ieee1275/ofpath.c (check_sas): Close fd.
index 8cdb2f61d22e0499caabcf4bbe7baff7339661cb..d61c90ec9742e38da6a2ccef95635cebfa1e4700 100644 (file)
@@ -39,6 +39,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
 #define JPEG_MARKER_DQT                0xdb
 #define JPEG_MARKER_SOF0       0xc0
 #define JPEG_MARKER_SOS                0xda
+#define JPEG_MARKER_DRI                0xdd
+#define JPEG_MARKER_RST0       0xd0
+#define JPEG_MARKER_RST1       0xd1
+#define JPEG_MARKER_RST2       0xd2
+#define JPEG_MARKER_RST3       0xd3
+#define JPEG_MARKER_RST4       0xd4
+#define JPEG_MARKER_RST5       0xd5
+#define JPEG_MARKER_RST6       0xd6
+#define JPEG_MARKER_RST7       0xd7
 
 #define SHIFT_BITS             8
 #define CONST(x)               ((int) ((x) * (1L << SHIFT_BITS) + 0.5))
@@ -66,6 +75,7 @@ struct grub_jpeg_data
 {
   grub_file_t file;
   struct grub_video_bitmap **bitmap;
+  grub_uint8_t *bitmap_ptr;
 
   int image_width;
   int image_height;
@@ -82,6 +92,8 @@ struct grub_jpeg_data
   jpeg_data_unit_t cbdu;
 
   int vs, hs;
+  int dri;
+  int r1;
 
   int dc_value[3];
 
@@ -315,6 +327,18 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
   return grub_errno;
 }
 
+static grub_err_t
+grub_jpeg_decode_dri (struct grub_jpeg_data *data)
+{
+  if (grub_jpeg_get_word (data) != 4)
+    return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+       "jpeg: DRI marker length must be 4");
+
+  data->dri = grub_jpeg_get_word (data);
+
+  return grub_errno;
+}
+
 static void
 grub_jpeg_idct_transform (jpeg_data_unit_t du)
 {
@@ -526,8 +550,7 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
 static grub_err_t
 grub_jpeg_decode_sos (struct grub_jpeg_data *data)
 {
-  int i, cc, r1, c1, nr1, nc1, vb, hb;
-  grub_uint8_t *ptr1;
+  int i, cc;
   grub_uint32_t data_offset;
 
   data_offset = data->file->offset;
@@ -563,17 +586,25 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
                                GRUB_VIDEO_BLIT_FORMAT_RGB_888))
     return grub_errno;
 
-  data->bit_mask = 0x0;
+  data->bitmap_ptr = (*data->bitmap)->data;
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_jpeg_decode_data (struct grub_jpeg_data *data)
+{
+  int c1, vb, hb, nr1, nc1;
+  int rst = data->dri;
 
   vb = data->vs * 8;
   hb = data->hs * 8;
   nr1 = (data->image_height + vb - 1) / vb;
   nc1 = (data->image_width + hb - 1) / hb;
 
-  ptr1 = (*data->bitmap)->data;
-  for (r1 = 0; r1 < nr1;
-       r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3)
-    for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3)
+  for (; data->r1 < nr1 && (!data->dri || rst);
+       data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
+    for (c1 = 0;  c1 < nc1 && (!data->dri || rst);
+       c1++, rst--, data->bitmap_ptr += hb * 3)
       {
        int r2, c2, nr2, nc2;
        grub_uint8_t *ptr2;
@@ -588,10 +619,10 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
        if (grub_errno)
          return grub_errno;
 
-       nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb;
+       nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb;
        nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
 
-       ptr2 = ptr1;
+       ptr2 = data->bitmap_ptr;
        for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3)
          for (c2 = 0; c2 < nc2; c2++, ptr2 += 3)
            {
@@ -600,8 +631,7 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
              i0 = (r2 / data->vs) * 8 + (c2 / data->hs);
              cr = data->crdu[i0];
              cb = data->cbdu[i0];
-             yy =
-               data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
+             yy = data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
 
              grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2);
            }
@@ -610,6 +640,16 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
   return grub_errno;
 }
 
+static void
+grub_jpeg_reset (struct grub_jpeg_data *data)
+{
+  data->bit_mask = 0x0;
+
+  data->dc_value[0] = 0;
+  data->dc_value[1] = 0;
+  data->dc_value[2] = 0;
+}
+
 static grub_uint8_t
 grub_jpeg_get_marker (struct grub_jpeg_data *data)
 {
@@ -655,8 +695,22 @@ grub_jpeg_decode_jpeg (struct grub_jpeg_data *data)
        case JPEG_MARKER_SOF0:  /* Start Of Frame 0.  */
          grub_jpeg_decode_sof (data);
          break;
+       case JPEG_MARKER_DRI:   /* Define Restart Interval.  */
+         grub_jpeg_decode_dri (data);
+         break;
        case JPEG_MARKER_SOS:   /* Start Of Scan.  */
-         grub_jpeg_decode_sos (data);
+         if (grub_jpeg_decode_sos (data))
+           break;
+       case JPEG_MARKER_RST0:  /* Restart.  */
+       case JPEG_MARKER_RST1:
+       case JPEG_MARKER_RST2:
+       case JPEG_MARKER_RST3:
+       case JPEG_MARKER_RST4:
+       case JPEG_MARKER_RST5:
+       case JPEG_MARKER_RST6:
+       case JPEG_MARKER_RST7:
+         grub_jpeg_decode_data (data);
+         grub_jpeg_reset (data);
          break;
        case JPEG_MARKER_EOI:   /* End Of Image.  */
          return grub_errno;