2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2008 Free Software Foundation, Inc.
5
* GRUB is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19
#include <grub/bitmap.h>
20
#include <grub/types.h>
21
#include <grub/normal.h>
24
#include <grub/misc.h>
25
#include <grub/bufio.h>
27
/* Uncomment following define to enable JPEG debug. */
30
#define JPEG_ESC_CHAR 0xFF
32
#define JPEG_SAMPLING_1x1 0x11
34
#define JPEG_MARKER_SOI 0xd8
35
#define JPEG_MARKER_EOI 0xd9
36
#define JPEG_MARKER_DHT 0xc4
37
#define JPEG_MARKER_DQT 0xdb
38
#define JPEG_MARKER_SOF0 0xc0
39
#define JPEG_MARKER_SOS 0xda
42
#define CONST(x) ((int) ((x) * (1L << SHIFT_BITS) + 0.5))
44
#define JPEG_UNIT_SIZE 8
46
static const grub_uint8_t jpeg_zigzag_order[64] = {
47
0, 1, 8, 16, 9, 2, 3, 10,
48
17, 24, 32, 25, 18, 11, 4, 5,
49
12, 19, 26, 33, 40, 48, 41, 34,
50
27, 20, 13, 6, 7, 14, 21, 28,
51
35, 42, 49, 56, 57, 50, 43, 36,
52
29, 22, 15, 23, 30, 37, 44, 51,
53
58, 59, 52, 45, 38, 31, 39, 46,
54
53, 60, 61, 54, 47, 55, 62, 63
58
static grub_command_t cmd;
61
typedef int jpeg_data_unit_t[64];
66
struct grub_video_bitmap **bitmap;
71
grub_uint8_t *huff_value[4];
72
int huff_offset[4][16];
73
int huff_maxval[4][16];
75
grub_uint8_t quan_table[2][64];
78
jpeg_data_unit_t ydu[4];
79
jpeg_data_unit_t crdu;
80
jpeg_data_unit_t cbdu;
86
int bit_mask, bit_save;
90
grub_jpeg_get_byte (struct grub_jpeg_data *data)
95
grub_file_read (data->file, &r, 1);
101
grub_jpeg_get_word (struct grub_jpeg_data *data)
106
grub_file_read (data->file, &r, sizeof (grub_uint16_t));
108
return grub_be_to_cpu16 (r);
112
grub_jpeg_get_bit (struct grub_jpeg_data *data)
116
if (data->bit_mask == 0)
118
data->bit_save = grub_jpeg_get_byte (data);
119
if (data->bit_save == JPEG_ESC_CHAR)
121
if (grub_jpeg_get_byte (data) != 0)
123
grub_error (GRUB_ERR_BAD_FILE_TYPE,
124
"jpeg: invalid 0xFF in data stream");
128
data->bit_mask = 0x80;
131
ret = ((data->bit_save & data->bit_mask) != 0);
132
data->bit_mask >>= 1;
137
grub_jpeg_get_number (struct grub_jpeg_data *data, int num)
144
msb = value = grub_jpeg_get_bit (data);
145
for (i = 1; i < num; i++)
146
value = (value << 1) + (grub_jpeg_get_bit (data) != 0);
148
value += 1 - (1 << num);
154
grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id)
159
for (i = 0; i < 16; i++)
162
if (grub_jpeg_get_bit (data))
164
if (code < data->huff_maxval[id][i])
165
return data->huff_value[id][code + data->huff_offset[id][i]];
167
grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: huffman decode fails");
172
grub_jpeg_decode_huff_table (struct grub_jpeg_data *data)
174
int id, ac, i, n, base, ofs;
175
grub_uint32_t next_marker;
176
grub_uint8_t count[16];
178
next_marker = data->file->offset;
179
next_marker += grub_jpeg_get_word (data);
181
id = grub_jpeg_get_byte (data);
185
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
186
"jpeg: too many huffman tables");
188
if (grub_file_read (data->file, &count, sizeof (count)) !=
193
for (i = 0; i < 16; i++)
197
data->huff_value[id] = grub_malloc (n);
201
if (grub_file_read (data->file, data->huff_value[id], n) != n)
206
for (i = 0; i < 16; i++)
211
data->huff_maxval[id][i] = base;
212
data->huff_offset[id][i] = ofs - base;
217
if (data->file->offset != next_marker)
218
grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table");
224
grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
227
grub_uint32_t next_marker;
229
next_marker = data->file->offset;
230
next_marker += grub_jpeg_get_word (data);
232
id = grub_jpeg_get_byte (data);
233
if (id >= 0x10) /* Upper 4-bit is precision. */
234
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
235
"jpeg: only 8-bit precision is supported");
238
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
239
"jpeg: too many quantization tables");
241
if (grub_file_read (data->file, &data->quan_table[id], 64) != 64)
244
if (data->file->offset != next_marker)
245
grub_error (GRUB_ERR_BAD_FILE_TYPE,
246
"jpeg: extra byte in quantization table");
252
grub_jpeg_decode_sof (struct grub_jpeg_data *data)
255
grub_uint32_t next_marker;
257
next_marker = data->file->offset;
258
next_marker += grub_jpeg_get_word (data);
260
if (grub_jpeg_get_byte (data) != 8)
261
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
262
"jpeg: only 8-bit precision is supported");
264
data->image_height = grub_jpeg_get_word (data);
265
data->image_width = grub_jpeg_get_word (data);
267
if ((!data->image_height) || (!data->image_width))
268
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size");
270
cc = grub_jpeg_get_byte (data);
272
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
273
"jpeg: component count must be 3");
275
for (i = 0; i < cc; i++)
279
id = grub_jpeg_get_byte (data) - 1;
280
if ((id < 0) || (id >= 3))
281
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
283
ss = grub_jpeg_get_byte (data); /* Sampling factor. */
286
data->vs = ss & 0xF; /* Vertical sampling. */
287
data->hs = ss >> 4; /* Horizontal sampling. */
288
if ((data->vs > 2) || (data->hs > 2))
289
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
290
"jpeg: sampling method not supported");
292
else if (ss != JPEG_SAMPLING_1x1)
293
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
294
"jpeg: sampling method not supported");
295
data->comp_index[id][0] = grub_jpeg_get_byte (data);
298
if (data->file->offset != next_marker)
299
grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sof");
305
grub_jpeg_idct_transform (jpeg_data_unit_t du)
309
int t0, t1, t2, t3, t4, t5, t6, t7;
310
int v0, v1, v2, v3, v4;
313
for (i = 0; i < JPEG_UNIT_SIZE; i++, pd++)
315
if ((pd[JPEG_UNIT_SIZE * 1] | pd[JPEG_UNIT_SIZE * 2] |
316
pd[JPEG_UNIT_SIZE * 3] | pd[JPEG_UNIT_SIZE * 4] |
317
pd[JPEG_UNIT_SIZE * 5] | pd[JPEG_UNIT_SIZE * 6] |
318
pd[JPEG_UNIT_SIZE * 7]) == 0)
320
pd[JPEG_UNIT_SIZE * 0] <<= SHIFT_BITS;
322
pd[JPEG_UNIT_SIZE * 1] = pd[JPEG_UNIT_SIZE * 2]
323
= pd[JPEG_UNIT_SIZE * 3] = pd[JPEG_UNIT_SIZE * 4]
324
= pd[JPEG_UNIT_SIZE * 5] = pd[JPEG_UNIT_SIZE * 6]
325
= pd[JPEG_UNIT_SIZE * 7] = pd[JPEG_UNIT_SIZE * 0];
330
t0 = pd[JPEG_UNIT_SIZE * 0];
331
t1 = pd[JPEG_UNIT_SIZE * 2];
332
t2 = pd[JPEG_UNIT_SIZE * 4];
333
t3 = pd[JPEG_UNIT_SIZE * 6];
335
v4 = (t1 + t3) * CONST (0.541196100);
337
v0 = ((t0 + t2) << SHIFT_BITS);
338
v1 = ((t0 - t2) << SHIFT_BITS);
339
v2 = v4 - t3 * CONST (1.847759065);
340
v3 = v4 + t1 * CONST (0.765366865);
347
t4 = pd[JPEG_UNIT_SIZE * 7];
348
t5 = pd[JPEG_UNIT_SIZE * 5];
349
t6 = pd[JPEG_UNIT_SIZE * 3];
350
t7 = pd[JPEG_UNIT_SIZE * 1];
357
v4 = (v2 + v3) * CONST (1.175875602);
359
v0 *= CONST (0.899976223);
360
v1 *= CONST (2.562915447);
361
v2 = v2 * CONST (1.961570560) - v4;
362
v3 = v3 * CONST (0.390180644) - v4;
364
t4 = t4 * CONST (0.298631336) - v0 - v2;
365
t5 = t5 * CONST (2.053119869) - v1 - v3;
366
t6 = t6 * CONST (3.072711026) - v1 - v2;
367
t7 = t7 * CONST (1.501321110) - v0 - v3;
369
pd[JPEG_UNIT_SIZE * 0] = t0 + t7;
370
pd[JPEG_UNIT_SIZE * 7] = t0 - t7;
371
pd[JPEG_UNIT_SIZE * 1] = t1 + t6;
372
pd[JPEG_UNIT_SIZE * 6] = t1 - t6;
373
pd[JPEG_UNIT_SIZE * 2] = t2 + t5;
374
pd[JPEG_UNIT_SIZE * 5] = t2 - t5;
375
pd[JPEG_UNIT_SIZE * 3] = t3 + t4;
376
pd[JPEG_UNIT_SIZE * 4] = t3 - t4;
380
for (i = 0; i < JPEG_UNIT_SIZE; i++, pd += JPEG_UNIT_SIZE)
382
if ((pd[1] | pd[2] | pd[3] | pd[4] | pd[5] | pd[6] | pd[7]) == 0)
384
pd[0] >>= (SHIFT_BITS + 3);
385
pd[1] = pd[2] = pd[3] = pd[4] = pd[5] = pd[6] = pd[7] = pd[0];
389
v4 = (pd[2] + pd[6]) * CONST (0.541196100);
391
v0 = (pd[0] + pd[4]) << SHIFT_BITS;
392
v1 = (pd[0] - pd[4]) << SHIFT_BITS;
393
v2 = v4 - pd[6] * CONST (1.847759065);
394
v3 = v4 + pd[2] * CONST (0.765366865);
411
v4 = (v2 + v3) * CONST (1.175875602);
413
v0 *= CONST (0.899976223);
414
v1 *= CONST (2.562915447);
415
v2 = v2 * CONST (1.961570560) - v4;
416
v3 = v3 * CONST (0.390180644) - v4;
418
t4 = t4 * CONST (0.298631336) - v0 - v2;
419
t5 = t5 * CONST (2.053119869) - v1 - v3;
420
t6 = t6 * CONST (3.072711026) - v1 - v2;
421
t7 = t7 * CONST (1.501321110) - v0 - v3;
423
pd[0] = (t0 + t7) >> (SHIFT_BITS * 2 + 3);
424
pd[7] = (t0 - t7) >> (SHIFT_BITS * 2 + 3);
425
pd[1] = (t1 + t6) >> (SHIFT_BITS * 2 + 3);
426
pd[6] = (t1 - t6) >> (SHIFT_BITS * 2 + 3);
427
pd[2] = (t2 + t5) >> (SHIFT_BITS * 2 + 3);
428
pd[5] = (t2 - t5) >> (SHIFT_BITS * 2 + 3);
429
pd[3] = (t3 + t4) >> (SHIFT_BITS * 2 + 3);
430
pd[4] = (t3 - t4) >> (SHIFT_BITS * 2 + 3);
433
for (i = 0; i < JPEG_UNIT_SIZE * JPEG_UNIT_SIZE; i++)
445
grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
449
grub_memset (du, 0, sizeof (jpeg_data_unit_t));
451
qt = data->comp_index[id][0];
452
h1 = data->comp_index[id][1];
453
h2 = data->comp_index[id][2];
455
data->dc_value[id] +=
456
grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1));
458
du[0] = data->dc_value[id] * (int) data->quan_table[qt][0];
464
num = grub_jpeg_get_huff_code (data, h2);
468
val = grub_jpeg_get_number (data, num & 0xF);
471
du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
475
grub_jpeg_idct_transform (du);
479
grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
487
dd = yy + ((cr * CONST (1.402)) >> SHIFT_BITS);
495
dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS);
503
dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS);
512
grub_jpeg_decode_sos (struct grub_jpeg_data *data)
514
int i, cc, r1, c1, nr1, nc1, vb, hb;
516
grub_uint32_t data_offset;
518
data_offset = data->file->offset;
519
data_offset += grub_jpeg_get_word (data);
521
cc = grub_jpeg_get_byte (data);
524
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
525
"jpeg: component count must be 3");
527
for (i = 0; i < cc; i++)
531
id = grub_jpeg_get_byte (data) - 1;
532
if ((id < 0) || (id >= 3))
533
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index");
535
ht = grub_jpeg_get_byte (data);
536
data->comp_index[id][1] = (ht >> 4);
537
data->comp_index[id][2] = (ht & 0xF) + 2;
540
grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */
541
grub_jpeg_get_word (data);
543
if (data->file->offset != data_offset)
544
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos");
546
if (grub_video_bitmap_create (data->bitmap, data->image_width,
548
GRUB_VIDEO_BLIT_FORMAT_RGB_888))
551
data->bit_mask = 0x0;
555
nr1 = (data->image_height + vb - 1) / vb;
556
nc1 = (data->image_width + hb - 1) / hb;
558
ptr1 = (*data->bitmap)->data;
559
for (r1 = 0; r1 < nr1;
560
r1++, ptr1 += (vb * data->image_width - hb * nc1) * 3)
561
for (c1 = 0; c1 < nc1; c1++, ptr1 += hb * 3)
563
int r2, c2, nr2, nc2;
566
for (r2 = 0; r2 < data->vs; r2++)
567
for (c2 = 0; c2 < data->hs; c2++)
568
grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]);
570
grub_jpeg_decode_du (data, 1, data->cbdu);
571
grub_jpeg_decode_du (data, 2, data->crdu);
576
nr2 = (r1 == nr1 - 1) ? (data->image_height - r1 * vb) : vb;
577
nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb;
580
for (r2 = 0; r2 < nr2; r2++, ptr2 += (data->image_width - nc2) * 3)
581
for (c2 = 0; c2 < nc2; c2++, ptr2 += 3)
585
i0 = (r2 / data->vs) * 8 + (c2 / data->hs);
589
data->ydu[(r2 / 8) * 2 + (c2 / 8)][(r2 % 8) * 8 + (c2 % 8)];
591
grub_jpeg_ycrcb_to_rgb (yy, cr, cb, ptr2);
599
grub_jpeg_get_marker (struct grub_jpeg_data *data)
603
r = grub_jpeg_get_byte (data);
605
if (r != JPEG_ESC_CHAR)
607
grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid maker");
611
return grub_jpeg_get_byte (data);
615
grub_jpeg_decode_jpeg (struct grub_jpeg_data *data)
617
if (grub_jpeg_get_marker (data) != JPEG_MARKER_SOI) /* Start Of Image. */
618
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid jpeg file");
620
while (grub_errno == 0)
624
marker = grub_jpeg_get_marker (data);
629
grub_printf ("jpeg marker: %x\n", marker);
634
case JPEG_MARKER_DHT: /* Define Huffman Table. */
635
grub_jpeg_decode_huff_table (data);
637
case JPEG_MARKER_DQT: /* Define Quantization Table. */
638
grub_jpeg_decode_quan_table (data);
640
case JPEG_MARKER_SOF0: /* Start Of Frame 0. */
641
grub_jpeg_decode_sof (data);
643
case JPEG_MARKER_SOS: /* Start Of Scan. */
644
grub_jpeg_decode_sos (data);
646
case JPEG_MARKER_EOI: /* End Of Image. */
648
default: /* Skip unrecognized marker. */
652
sz = grub_jpeg_get_word (data);
655
grub_file_seek (data->file, data->file->offset + sz - 2);
664
grub_video_reader_jpeg (struct grub_video_bitmap **bitmap,
665
const char *filename)
668
struct grub_jpeg_data *data;
670
file = grub_buffile_open (filename, 0);
674
data = grub_zalloc (sizeof (*data));
680
data->bitmap = bitmap;
681
grub_jpeg_decode_jpeg (data);
683
for (i = 0; i < 4; i++)
684
if (data->huff_value[i])
685
grub_free (data->huff_value[i]);
690
if (grub_errno != GRUB_ERR_NONE)
692
grub_video_bitmap_destroy (*bitmap);
696
grub_file_close (file);
700
#if defined(JPEG_DEBUG)
702
grub_cmd_jpegtest (grub_command_t cmd __attribute__ ((unused)),
703
int argc, char **args)
705
struct grub_video_bitmap *bitmap = 0;
708
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
710
grub_video_reader_jpeg (&bitmap, args[0]);
711
if (grub_errno != GRUB_ERR_NONE)
714
grub_video_bitmap_destroy (bitmap);
716
return GRUB_ERR_NONE;
720
static struct grub_video_bitmap_reader jpg_reader = {
722
.reader = grub_video_reader_jpeg,
726
static struct grub_video_bitmap_reader jpeg_reader = {
727
.extension = ".jpeg",
728
.reader = grub_video_reader_jpeg,
732
GRUB_MOD_INIT (video_reader_jpeg)
734
grub_video_bitmap_reader_register (&jpg_reader);
735
grub_video_bitmap_reader_register (&jpeg_reader);
736
#if defined(JPEG_DEBUG)
737
cmd = grub_register_command ("jpegtest", grub_cmd_jpegtest,
739
"Tests loading of JPEG bitmap.");
743
GRUB_MOD_FINI (video_reader_jpeg)
745
#if defined(JPEG_DEBUG)
746
grub_unregister_command (cmd);
748
grub_video_bitmap_reader_unregister (&jpeg_reader);
749
grub_video_bitmap_reader_unregister (&jpg_reader);