+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.
#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))
{
grub_file_t file;
struct grub_video_bitmap **bitmap;
+ grub_uint8_t *bitmap_ptr;
int image_width;
int image_height;
jpeg_data_unit_t cbdu;
int vs, hs;
+ int dri;
+ int r1;
int dc_value[3];
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)
{
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;
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;
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)
{
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);
}
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)
{
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;