aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-12-07 16:23:22 -0800
committerH. Peter Anvin <hpa@zytor.com>2009-12-07 16:23:22 -0800
commit2f74a2a8b56622951b2bad1ca19e61ad02eb9f03 (patch)
tree0208468772b4cffef6819d36b07f0b4ac9abb673 /com32
parent2c36092660d8666a2a50c73da66717208b94eb4f (diff)
parent66a4a0bab62d10c66386c1f879a606366c5aea99 (diff)
downloadsyslinux.git-2f74a2a8b56622951b2bad1ca19e61ad02eb9f03.tar.gz
syslinux.git-2f74a2a8b56622951b2bad1ca19e61ad02eb9f03.tar.xz
syslinux.git-2f74a2a8b56622951b2bad1ca19e61ad02eb9f03.zip
Merge branch 'softres'
Diffstat (limited to 'com32')
-rw-r--r--com32/include/syslinux/vesacon.h1
-rw-r--r--com32/lib/Makefile3
-rw-r--r--com32/lib/jpeg/bgr24.c135
-rw-r--r--com32/lib/jpeg/bgra32.c158
-rw-r--r--com32/lib/jpeg/grey.c87
-rw-r--r--com32/lib/jpeg/jidctflt.c22
-rw-r--r--com32/lib/jpeg/rgb24.c135
-rw-r--r--com32/lib/jpeg/rgba32.c155
-rw-r--r--com32/lib/jpeg/tinyjpeg-internal.h45
-rw-r--r--com32/lib/jpeg/tinyjpeg.c243
-rw-r--r--com32/lib/jpeg/yuv420p.c133
-rw-r--r--com32/lib/sys/vesa/background.c56
-rw-r--r--com32/lib/sys/vesa/drawtxt.c48
-rw-r--r--com32/lib/sys/vesa/initvesa.c47
-rw-r--r--com32/lib/sys/vesa/video.h23
-rw-r--r--com32/lib/sys/vesacon_write.c18
-rw-r--r--com32/menu/menu.c9
-rw-r--r--com32/menu/menu.h6
-rw-r--r--com32/menu/menumain.c12
-rw-r--r--com32/menu/readconfig.c5
-rw-r--r--com32/menu/vesamenu.c9
21 files changed, 796 insertions, 554 deletions
diff --git a/com32/include/syslinux/vesacon.h b/com32/include/syslinux/vesacon.h
index dad9fb57..11d72f3a 100644
--- a/com32/include/syslinux/vesacon.h
+++ b/com32/include/syslinux/vesacon.h
@@ -29,6 +29,7 @@
#define _SYSLINUX_VESACON_H
int vesacon_default_background(void);
+void vesacon_set_resolution(int, int);
int vesacon_load_background(const char *);
int vesacon_set_background(unsigned int);
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index d136d2b3..ad77bcd6 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -80,7 +80,8 @@ LIBOBJS = \
libpng/pngerror.o libpng/pngpread.o \
\
jpeg/tinyjpeg.o jpeg/jidctflt.o jpeg/decode1.o jpeg/decode3.o \
- jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o \
+ jpeg/grey.o jpeg/yuv420p.o \
+ jpeg/rgb24.o jpeg/bgr24.o \
jpeg/rgba32.o jpeg/bgra32.o \
\
sys/x86_init_fpu.o math/pow.o math/strtod.o \
diff --git a/com32/lib/jpeg/bgr24.c b/com32/lib/jpeg/bgr24.c
index ffdcbdf9..855b855f 100644
--- a/com32/lib/jpeg/bgr24.c
+++ b/com32/lib/jpeg/bgr24.c
@@ -69,7 +69,7 @@ static unsigned char clamp(int i)
* | 1 |
* `---'
*/
-static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
+static void YCrCB_to_BGR24_1x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -85,15 +85,14 @@ static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -107,6 +106,7 @@ static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
+ Y++;
}
p += offset_to_next_row;
@@ -125,7 +125,7 @@ static void YCrCB_to_BGR24_1x1(struct jdec_private *priv)
* | 1 | 2 |
* `-------'
*/
-static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
+static void YCrCB_to_BGR24_2x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -141,9 +141,8 @@ static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -155,15 +154,7 @@ static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -171,6 +162,17 @@ static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ }
+
+ Y += 2;
}
p += offset_to_next_row;
@@ -190,7 +192,7 @@ static void YCrCB_to_BGR24_2x1(struct jdec_private *priv)
* | 2 |
* `---'
*/
-static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
+static void YCrCB_to_BGR24_1x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -207,9 +209,8 @@ static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0 ; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -221,7 +222,7 @@ static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -229,14 +230,17 @@ static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
- y = (Y[8-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
-
+ if (i > 1) {
+ y = Y[8] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ }
+
+ Y++;
}
Y += 8;
p += offset_to_next_row;
@@ -258,7 +262,7 @@ static void YCrCB_to_BGR24_1x2(struct jdec_private *priv)
* | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
+static void YCrCB_to_BGR24_2x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -275,9 +279,8 @@ static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -289,7 +292,7 @@ static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -297,29 +300,37 @@ static void YCrCB_to_BGR24_2x2(struct jdec_private *priv)
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
-
- y = (Y[16-2]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
-
- y = (Y[16-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ }
+
+ if (i > 1) {
+ y = Y[16+0] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+
+ if (j > 1) {
+ y = Y[16+1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ }
+ }
+
+ Y += 2;
}
Y += 16;
p += offset_to_next_row;
@@ -336,12 +347,12 @@ static int initialize_bgr24(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
if (!priv->bytes_per_row[0])
priv->bytes_per_row[0] = priv->width * 3;
+ if (!priv->components[0])
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
+ bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
bytes_per_mcu[0] = 3*8;
return !priv->components[0];
diff --git a/com32/lib/jpeg/bgra32.c b/com32/lib/jpeg/bgra32.c
index 7e2c72bc..9a1ab309 100644
--- a/com32/lib/jpeg/bgra32.c
+++ b/com32/lib/jpeg/bgra32.c
@@ -69,7 +69,7 @@ static unsigned char clamp(int i)
* | 1 |
* `---'
*/
-static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv)
+static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -85,15 +85,14 @@ static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 8*4;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b, a;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -109,6 +108,7 @@ static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv)
a = 255;
*p++ = a;
+ Y++;
}
p += offset_to_next_row;
@@ -127,7 +127,7 @@ static void YCrCB_to_BGRA32_1x1(struct jdec_private *priv)
* | 1 | 2 |
* `-------'
*/
-static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv)
+static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -143,10 +143,8 @@ static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 16*4;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
-
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b, a;
@@ -157,7 +155,7 @@ static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -166,17 +164,20 @@ static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv)
*p++ = clamp(r);
a = 255;
*p++ = a;
-
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- a = 255;
- *p++ = a;
-
+
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ a = 255;
+ *p++ = a;
+ }
+
+ Y += 2;
}
p += offset_to_next_row;
@@ -196,7 +197,7 @@ static void YCrCB_to_BGRA32_2x1(struct jdec_private *priv)
* | 2 |
* `---'
*/
-static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv)
+static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -213,9 +214,8 @@ static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -227,7 +227,7 @@ static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -237,16 +237,19 @@ static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv)
a = 255;
*p++ = a;
- y = (Y[8-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- a = 255;
- *p2++ = a;
-
+ if (i > 1) {
+ y = Y[8] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ a = 255;
+ *p2++ = a;
+ }
+
+ Y++;
}
Y += 8;
p += offset_to_next_row;
@@ -268,7 +271,7 @@ static void YCrCB_to_BGRA32_1x2(struct jdec_private *priv)
* | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv)
+static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -285,9 +288,8 @@ static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -299,17 +301,7 @@ static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- a = 255;
- *p++ = a;
-
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
g = (y + add_g) >> SCALEBITS;
@@ -319,25 +311,43 @@ static void YCrCB_to_BGRA32_2x2(struct jdec_private *priv)
a = 255;
*p++ = a;
- y = (Y[16-2]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- a = 255;
- *p2++ = a;
-
- y = (Y[16-1]) << SCALEBITS;
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- a = 255;
- *p2++ = a;
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ a = 255;
+ *p++ = a;
+ }
+
+ if (i > 1) {
+ y = Y[16+0] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ a = 255;
+ *p2++ = a;
+
+ if (j > 1) {
+ y = Y[16+1] << SCALEBITS;
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ a = 255;
+ *p2++ = a;
+ }
+ }
+
+ Y += 2;
}
Y += 16;
p += offset_to_next_row;
@@ -354,12 +364,12 @@ static int initialize_bgra32(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 4);
if (!priv->bytes_per_row[0])
priv->bytes_per_row[0] = priv->width * 4;
+ if (!priv->components[0])
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
+ bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
bytes_per_mcu[0] = 4*8;
return !priv->components[0];
diff --git a/com32/lib/jpeg/grey.c b/com32/lib/jpeg/grey.c
index 0034ce2b..6710ede6 100644
--- a/com32/lib/jpeg/grey.c
+++ b/com32/lib/jpeg/grey.c
@@ -40,12 +40,12 @@
#include "tinyjpeg-internal.h"
/**
- * YCrCb -> Grey (1x1)
+ * YCrCb -> Grey (1x1, 1x2)
* .---.
* | 1 |
* `---'
*/
-static void YCrCB_to_Grey_1x1(struct jdec_private *priv)
+static void YCrCB_to_Grey_1xN(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *y;
unsigned char *p;
@@ -56,73 +56,20 @@ static void YCrCB_to_Grey_1x1(struct jdec_private *priv)
y = priv->Y;
offset_to_next_row = priv->bytes_per_row[0];
- for (i=0; i<8; i++) {
- memcpy(p, y, 8);
- y+=8;
- p += offset_to_next_row;
- }
-}
-
-/**
- * YCrCb -> Grey (2x1)
- * .-------.
- * | 1 | 2 |
- * `-------'
- */
-static void YCrCB_to_Grey_2x1(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
- int offset_to_next_row;
-
- p = priv->plane[0];
- y = priv->Y;
- offset_to_next_row = priv->bytes_per_row[0];
-
- for (i=0; i<8; i++) {
- memcpy(p, y, 16);
- y += 16;
- p += offset_to_next_row;
- }
-}
-
-
-/**
- * YCrCb -> Grey (1x2)
- * .---.
- * | 1 |
- * |---|
- * | 2 |
- * `---'
- */
-static void YCrCB_to_Grey_1x2(struct jdec_private *priv)
-{
- const unsigned char *y;
- unsigned char *p;
- unsigned int i;
- int offset_to_next_row;
-
- p = priv->plane[0];
- y = priv->Y;
- offset_to_next_row = priv->bytes_per_row[0];
-
- for (i=0; i<16; i++) {
- memcpy(p, y, 8);
+ for (i = sy; i > 0; i--) {
+ memcpy(p, y, sx);
y += 8;
p += offset_to_next_row;
}
}
/**
- * YCrCb -> Grey (2x2)
+ * YCrCb -> Grey (2x1, 2x2)
* .-------.
* | 1 | 2 |
- * |---+---|
- * | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_Grey_2x2(struct jdec_private *priv)
+static void YCrCB_to_Grey_2xN(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *y;
unsigned char *p;
@@ -133,8 +80,8 @@ static void YCrCB_to_Grey_2x2(struct jdec_private *priv)
y = priv->Y;
offset_to_next_row = priv->bytes_per_row[0];
- for (i=0; i<16; i++) {
- memcpy(p, y, 16);
+ for (i = sy; i > 0; i--) {
+ memcpy(p, y, sx);
y += 16;
p += offset_to_next_row;
}
@@ -144,13 +91,13 @@ static int initialize_grey(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
if (!priv->bytes_per_row[0])
- priv->bytes_per_row[0] = priv->width * 3;
+ priv->bytes_per_row[0] = priv->width;
+ if (!priv->components[0])
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
- bytes_per_mcu[0] = 3*8;
+ bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
+ bytes_per_mcu[0] = 8;
return !priv->components[0];
}
@@ -158,10 +105,10 @@ static int initialize_grey(struct jdec_private *priv,
static const struct tinyjpeg_colorspace format_grey =
{
{
- YCrCB_to_Grey_1x1,
- YCrCB_to_Grey_1x2,
- YCrCB_to_Grey_2x1,
- YCrCB_to_Grey_2x2,
+ YCrCB_to_Grey_1xN,
+ YCrCB_to_Grey_1xN,
+ YCrCB_to_Grey_2xN,
+ YCrCB_to_Grey_2xN,
},
tinyjpeg_decode_mcu_1comp_table,
initialize_grey
diff --git a/com32/lib/jpeg/jidctflt.c b/com32/lib/jpeg/jidctflt.c
index e5e66edc..6f0df772 100644
--- a/com32/lib/jpeg/jidctflt.c
+++ b/com32/lib/jpeg/jidctflt.c
@@ -80,7 +80,7 @@
#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
-#if defined(__GNUC__) && defined(__i686__) || defined(__x86_64__)
+#if 1 && defined(__GNUC__) && (defined(__i686__) || defined(__x86_64__))
static inline unsigned char descale_and_clamp(int x, int shift)
{
@@ -92,7 +92,7 @@ static inline unsigned char descale_and_clamp(int x, int shift)
"\tcmpl %4,%1\n"
"\tcmovg %4,%1\n"
: "=r"(x)
- : "0"(x), "i"(shift), "i"(1UL<<(shift-1)), "r" (0xff), "r" (0)
+ : "0"(x), "Ir"(shift), "ir"(1UL<<(shift-1)), "r" (0xff), "r" (0)
);
return x;
}
@@ -120,7 +120,7 @@ static inline unsigned char descale_and_clamp(int x, int shift)
*/
void
-jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
+tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
{
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -269,14 +269,14 @@ jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride)
/* Final output stage: scale down by a factor of 8 and range-limit */
- outptr[0] = descale_and_clamp(tmp0 + tmp7, 3);
- outptr[7] = descale_and_clamp(tmp0 - tmp7, 3);
- outptr[1] = descale_and_clamp(tmp1 + tmp6, 3);
- outptr[6] = descale_and_clamp(tmp1 - tmp6, 3);
- outptr[2] = descale_and_clamp(tmp2 + tmp5, 3);
- outptr[5] = descale_and_clamp(tmp2 - tmp5, 3);
- outptr[4] = descale_and_clamp(tmp3 + tmp4, 3);
- outptr[3] = descale_and_clamp(tmp3 - tmp4, 3);
+ outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3);
+ outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3);
+ outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3);
+ outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3);
+ outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3);
+ outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3);
+ outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3);
+ outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3);
wsptr += DCTSIZE; /* advance pointer to next row */
diff --git a/com32/lib/jpeg/rgb24.c b/com32/lib/jpeg/rgb24.c
index e37cc77d..e1481f31 100644
--- a/com32/lib/jpeg/rgb24.c
+++ b/com32/lib/jpeg/rgb24.c
@@ -69,7 +69,7 @@ static unsigned char clamp(int i)
* | 1 |
* `---'
*/
-static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
+static void YCrCB_to_RGB24_1x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -85,15 +85,13 @@ static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
-
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j++) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -107,6 +105,7 @@ static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
+ Y++;
}
p += offset_to_next_row;
@@ -124,7 +123,7 @@ static void YCrCB_to_RGB24_1x1(struct jdec_private *priv)
* | 1 | 2 |
* `-------'
*/
-static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
+static void YCrCB_to_RGB24_2x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -140,15 +139,15 @@ static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 16*3;
- for (i=0; i<8; i++) {
+ for (i = sy; i > 0; i--) {
- for (j=0; j<8; j++) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -162,14 +161,17 @@ static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ }
+
+ Y += 2;
}
p += offset_to_next_row;
@@ -190,7 +192,7 @@ static void YCrCB_to_RGB24_2x1(struct jdec_private *priv)
* | 2 |
* `---'
*/
-static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
+static void YCrCB_to_RGB24_1x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -207,9 +209,8 @@ static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 8*3;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -221,7 +222,7 @@ static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
g = (y + add_g) >> SCALEBITS;
@@ -229,14 +230,17 @@ static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
- y = (Y[8-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
-
+ if (i > 1) {
+ y = Y[8] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ }
+
+ Y++;
}
Y += 8;
p += offset_to_next_row;
@@ -257,7 +261,7 @@ static void YCrCB_to_RGB24_1x2(struct jdec_private *priv)
* | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
+static void YCrCB_to_RGB24_2x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -274,9 +278,8 @@ static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 16*3;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -288,7 +291,7 @@ static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
g = (y + add_g) >> SCALEBITS;
@@ -296,29 +299,37 @@ static void YCrCB_to_RGB24_2x2(struct jdec_private *priv)
b = (y + add_b) >> SCALEBITS;
*p++ = clamp(b);
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
-
- y = (Y[16-2]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
-
- y = (Y[16-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ }
+
+ if (i > 1) {
+ y = Y[16+0] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+
+ if (j > 1) {
+ y = Y[16+1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ }
+ }
+
+ Y += 2;
}
Y += 16;
p += offset_to_next_row;
@@ -335,12 +346,12 @@ static int initialize_rgb24(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 3);
if (!priv->bytes_per_row[0])
priv->bytes_per_row[0] = priv->width * 3;
+ if (priv->components[0] == NULL)
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
+ bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
bytes_per_mcu[0] = 3*8;
return !priv->components[0];
diff --git a/com32/lib/jpeg/rgba32.c b/com32/lib/jpeg/rgba32.c
index 5fcbe992..d04f0f13 100644
--- a/com32/lib/jpeg/rgba32.c
+++ b/com32/lib/jpeg/rgba32.c
@@ -69,7 +69,7 @@ static unsigned char clamp(int i)
* | 1 |
* `---'
*/
-static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv)
+static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -85,15 +85,14 @@ static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 8*4;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b, a;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -108,6 +107,8 @@ static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv)
*p++ = clamp(b);
a = 255;
*p++ = a;
+
+ Y++;
}
p += offset_to_next_row;
@@ -125,7 +126,7 @@ static void YCrCB_to_RGBA32_1x1(struct jdec_private *priv)
* | 1 | 2 |
* `-------'
*/
-static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv)
+static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p;
@@ -141,15 +142,14 @@ static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = priv->bytes_per_row[0] - 16*4;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i--) {
+ for (j = sx; j > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
int r, g , b, a;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
cb = *Cb++ - 128;
cr = *Cr++ - 128;
add_r = FIX(1.40200) * cr + ONE_HALF;
@@ -165,15 +165,19 @@ static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv)
a = 255;
*p++ = a;
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- a = 255;
- *p++ = a;
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ a = 255;
+ *p++ = a;
+ }
+
+ Y += 2;
}
p += offset_to_next_row;
@@ -194,7 +198,7 @@ static void YCrCB_to_RGBA32_2x1(struct jdec_private *priv)
* | 2 |
* `---'
*/
-static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv)
+static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -211,9 +215,8 @@ static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 8*4;
- for (i=0; i<8; i++) {
-
- for (j=0; j<8; j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; j > 0; j--) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -225,7 +228,7 @@ static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
g = (y + add_g) >> SCALEBITS;
@@ -235,16 +238,19 @@ static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv)
a = 255;
*p++ = a;
- y = (Y[8-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- a = 255;
- *p2++ = a;
-
+ if (i > 1) {
+ y = Y[8] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ a = 255;
+ *p2++ = a;
+ }
+
+ Y++;
}
Y += 8;
p += offset_to_next_row;
@@ -265,7 +271,7 @@ static void YCrCB_to_RGBA32_1x2(struct jdec_private *priv)
* | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv)
+static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *Y, *Cb, *Cr;
unsigned char *p, *p2;
@@ -282,9 +288,8 @@ static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv)
Cb = priv->Cb;
Cr = priv->Cr;
offset_to_next_row = 2*priv->bytes_per_row[0] - 16*4;
- for (i=0; i<8; i++) {
-
- for (j=0;j<8;j++) {
+ for (i = sy; i > 0; i -= 2) {
+ for (j = sx; i > 0; j -= 2) {
int y, cb, cr;
int add_r, add_g, add_b;
@@ -296,7 +301,7 @@ static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv)
add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;
add_b = FIX(1.77200) * cb + ONE_HALF;
- y = (*Y++) << SCALEBITS;
+ y = Y[0] << SCALEBITS;
r = (y + add_r) >> SCALEBITS;
*p++ = clamp(r);
g = (y + add_g) >> SCALEBITS;
@@ -306,35 +311,43 @@ static void YCrCB_to_RGBA32_2x2(struct jdec_private *priv)
a = 255;
*p++ = a;
- y = (*Y++) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p++ = clamp(b);
- a = 255;
- *p++ = a;
-
- y = (Y[16-2]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- a = 255;
- *p2++ = a;
-
- y = (Y[16-1]) << SCALEBITS;
- r = (y + add_r) >> SCALEBITS;
- *p2++ = clamp(r);
- g = (y + add_g) >> SCALEBITS;
- *p2++ = clamp(g);
- b = (y + add_b) >> SCALEBITS;
- *p2++ = clamp(b);
- a = 255;
- *p2++ = a;
+ if (j > 1) {
+ y = Y[1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p++ = clamp(b);
+ a = 255;
+ *p++ = a;
+ }
+
+ if (i > 1) {
+ y = Y[16+0] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ a = 255;
+ *p2++ = a;
+
+ if (j > 1) {
+ y = Y[16+1] << SCALEBITS;
+ r = (y + add_r) >> SCALEBITS;
+ *p2++ = clamp(r);
+ g = (y + add_g) >> SCALEBITS;
+ *p2++ = clamp(g);
+ b = (y + add_b) >> SCALEBITS;
+ *p2++ = clamp(b);
+ a = 255;
+ *p2++ = a;
+ }
+ }
+
+ Y += 2;
}
Y += 16;
p += offset_to_next_row;
@@ -351,12 +364,12 @@ static int initialize_rgba32(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height * 4);
if (!priv->bytes_per_row[0])
priv->bytes_per_row[0] = priv->width * 4;
+ if (!priv->components[0])
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
+ bytes_per_blocklines[0] = priv->bytes_per_row[0] << 3;
bytes_per_mcu[0] = 4*8;
return !priv->components[0];
diff --git a/com32/lib/jpeg/tinyjpeg-internal.h b/com32/lib/jpeg/tinyjpeg-internal.h
index 78cb0421..bb5c6707 100644
--- a/com32/lib/jpeg/tinyjpeg-internal.h
+++ b/com32/lib/jpeg/tinyjpeg-internal.h
@@ -35,14 +35,21 @@
#ifndef __TINYJPEG_INTERNAL_H_
#define __TINYJPEG_INTERNAL_H_
+#include <setjmp.h>
+
+#define SANITY_CHECK 1
+
struct jdec_private;
+#define HUFFMAN_BITS_SIZE 256
#define HUFFMAN_HASH_NBITS 9
#define HUFFMAN_HASH_SIZE (1UL<<HUFFMAN_HASH_NBITS)
#define HUFFMAN_HASH_MASK (HUFFMAN_HASH_SIZE-1)
#define HUFFMAN_TABLES 4
-#define COMPONENTS 4
+#define COMPONENTS 3
+#define JPEG_MAX_WIDTH 4096
+#define JPEG_MAX_HEIGHT 4096
struct huffman_table
{
@@ -66,11 +73,14 @@ struct component
struct huffman_table *DC_table;
short int previous_DC; /* Previous DC coefficient */
short int DCT[64]; /* DCT coef */
+#if SANITY_CHECK
+ unsigned int cid;
+#endif
};
typedef void (*decode_MCU_fct) (struct jdec_private *priv);
-typedef void (*convert_colorspace_fct) (struct jdec_private *priv);
+typedef void (*convert_colorspace_fct) (struct jdec_private *priv, int, int);
struct jdec_private
{
@@ -81,7 +91,7 @@ struct jdec_private
unsigned int flags;
/* Private variables */
- const unsigned char *stream_begin;
+ const unsigned char *stream_begin, *stream_end;
unsigned int stream_length;
const unsigned char *stream; /* Pointer to the current stream */
@@ -92,24 +102,28 @@ struct jdec_private
struct huffman_table HTDC[HUFFMAN_TABLES]; /* DC huffman tables */
struct huffman_table HTAC[HUFFMAN_TABLES]; /* AC huffman tables */
int default_huffman_table_initialized;
+ int restart_interval;
+ int restarts_to_go; /* MCUs left in this restart interval */
+ int last_rst_marker_seen; /* Rst marker is incremented each time */
/* Temp space used after the IDCT to store each components */
uint8_t Y[64*4], Cr[64], Cb[64];
+ jmp_buf jump_state;
/* Internal Pointer use for colorspace conversion, do not modify it !!! */
uint8_t *plane[COMPONENTS];
};
+#define IDCT tinyjpeg_idct_float
+void tinyjpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
+
struct tinyjpeg_colorspace {
convert_colorspace_fct convert_colorspace[4];
const decode_MCU_fct *decode_mcu_table;
int (*initialize)(struct jdec_private *, unsigned int *, unsigned int *);
};
-#define IDCT jpeg_idct_float
-void jpeg_idct_float (struct component *compptr, uint8_t *output_buf, int stride);
-
void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component);
extern const decode_MCU_fct tinyjpeg_decode_mcu_3comp_table[4];
@@ -121,13 +135,16 @@ enum std_markers {
DHT = 0xC4, /* Huffman Table */
SOI = 0xD8, /* Start of Image */
SOS = 0xDA, /* Start of Scan */
+ RST = 0xD0, /* Reset Marker d0 -> .. */
+ RST7 = 0xD7, /* Reset Marker .. -> d7 */
EOI = 0xD9, /* End of Image */
+ DRI = 0xDD, /* Define Restart Interval */
APP0 = 0xE0,
};
-#define cY 1
-#define cCb 2
-#define cCr 3
+#define cY 0
+#define cCb 1
+#define cCr 2
#define BLACK_Y 0
#define BLACK_U 127
@@ -150,6 +167,16 @@ enum std_markers {
#define trace(fmt, args...) do { } while (0)
#endif
+#ifndef __likely
+# define __likely(x) (!!(x))
+#endif
+#ifndef __unlikely
+# define __unlikely(x) (!!(x))
+#endif
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#define max(x, y) ((x) > (y) ? (x) : (y))
+
#if 0
static char *print_bits(unsigned int value, char *bitstr)
{
diff --git a/com32/lib/jpeg/tinyjpeg.c b/com32/lib/jpeg/tinyjpeg.c
index f8e881f0..3c6070f4 100644
--- a/com32/lib/jpeg/tinyjpeg.c
+++ b/com32/lib/jpeg/tinyjpeg.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <errno.h>
#include "tinyjpeg.h"
#include "tinyjpeg-internal.h"
@@ -162,7 +163,10 @@ static const unsigned char val_ac_chrominance[] =
#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
while (nbits_in_reservoir<nbits_wanted) \
{ \
- const unsigned char c = *stream++; \
+ unsigned char c; \
+ if (stream >= priv->stream_end) \
+ longjmp(priv->jump_state, -EIO); \
+ c = *stream++; \
reservoir <<= 8; \
if (c == 0xff && *stream == 0x00) \
stream++; \
@@ -177,7 +181,7 @@ static const unsigned char val_ac_chrominance[] =
result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
nbits_in_reservoir -= (nbits_wanted); \
reservoir &= ((1U<<nbits_in_reservoir)-1); \
- if (result < (1UL<<((nbits_wanted)-1))) \
+ if ((unsigned int)result < (1UL<<((nbits_wanted)-1))) \
result += (0xFFFFFFFFUL<<(nbits_wanted))+1; \
} while(0);
@@ -186,8 +190,15 @@ static const unsigned char val_ac_chrominance[] =
result = ((reservoir)>>(nbits_in_reservoir-(nbits_wanted))); \
} while(0);
+/* To speed up the decoding, we assume that the reservoir have enough bit
+ * slow version:
+ * #define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
+ * fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
+ * nbits_in_reservoir -= (nbits_wanted); \
+ * reservoir &= ((1U<<nbits_in_reservoir)-1); \
+ * } while(0);
+ */
#define skip_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \
- fill_nbits(reservoir,nbits_in_reservoir,stream,(nbits_wanted)); \
nbits_in_reservoir -= (nbits_wanted); \
reservoir &= ((1U<<nbits_in_reservoir)-1); \
} while(0);
@@ -195,6 +206,7 @@ static const unsigned char val_ac_chrominance[] =
#define be16_to_cpu(x) (((x)[0]<<8)|(x)[1])
+static void resync(struct jdec_private *priv);
/**
* Get the next (valid) huffman code in the stream.
@@ -215,9 +227,9 @@ static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table
look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, HUFFMAN_HASH_NBITS, hcode);
value = huffman_table->lookup[hcode];
- if (value>=0)
+ if (__likely(value >= 0))
{
- int code_size = huffman_table->code_size[value];
+ unsigned int code_size = huffman_table->code_size[value];
skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, code_size);
return value;
}
@@ -253,17 +265,19 @@ static int get_next_huffman_code(struct jdec_private *priv, struct huffman_table
void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component)
{
unsigned char j;
- int huff_code;
+ unsigned int huff_code;
unsigned char size_val, count_0;
struct component *c = &priv->component_infos[component];
short int DCT[64];
+
/* Initialize the DCT coef table */
memset(DCT, 0, sizeof(DCT));
/* DC coefficient decoding */
huff_code = get_next_huffman_code(priv, c->DC_table);
+ //trace("+ %x\n", huff_code);
if (huff_code) {
get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]);
DCT[0] += c->previous_DC;
@@ -277,6 +291,7 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
while (j<64)
{
huff_code = get_next_huffman_code(priv, c->AC_table);
+ //trace("- %x\n", huff_code);
size_val = huff_code & 0xF;
count_0 = huff_code >> 4;
@@ -291,6 +306,11 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
else
{
j += count_0; /* skip count_0 zeroes */
+ if (__unlikely(j >= 64))
+ {
+ snprintf(error_string, sizeof(error_string), "Bad huffman data (buffer overflow)");
+ break;
+ }
get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]);
j++;
}
@@ -298,7 +318,6 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
for (j = 0; j < 64; j++)
c->DCT[j] = DCT[zigzag[j]];
-
}
/*
@@ -311,8 +330,8 @@ void tinyjpeg_process_Huffman_data_unit(struct jdec_private *priv, int component
static void build_huffman_table(const unsigned char *bits, const unsigned char *vals, struct huffman_table *table)
{
unsigned int i, j, code, code_size, val, nbits;
- unsigned char huffsize[257], *hz;
- unsigned int huffcode[257], *hc;
+ unsigned char huffsize[HUFFMAN_BITS_SIZE+1], *hz;
+ unsigned int huffcode[HUFFMAN_BITS_SIZE+1], *hc;
int next_free_entry;
/*
@@ -340,10 +359,11 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
nbits = *hz;
while (*hz)
{
- while (*hz == nbits) {
+ while (*hz == nbits)
+ {
*hc++ = code++;
hz++;
- }
+ }
code <<= 1;
nbits++;
}
@@ -358,7 +378,7 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
code = huffcode[i];
code_size = huffsize[i];
- trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size);
+ trace("val=%2.2x code=%8.8x codesize=%2.2d\n", val, code, code_size);
table->code_size[val] = code_size;
if (code_size <= HUFFMAN_HASH_NBITS)
@@ -386,7 +406,6 @@ static void build_huffman_table(const unsigned char *bits, const unsigned char *
}
}
-
}
static void build_default_huffman_tables(struct jdec_private *priv)
@@ -483,14 +502,15 @@ static void build_quantization_table(float *qtable, const unsigned char *ref_tab
static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
{
- int length, qi;
+ int qi;
float *table;
+ const unsigned char *dqt_block_end;
trace("> DQT marker\n");
- length = be16_to_cpu(stream) - 2;
+ dqt_block_end = stream + be16_to_cpu(stream);
stream += 2; /* Skip length */
- while (length>0)
+ while (stream < dqt_block_end)
{
qi = *stream++;
#if SANITY_CHECK
@@ -502,8 +522,8 @@ static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
table = priv->Q_tables[qi];
build_quantization_table(table, stream);
stream += 64;
- length -= 65;
}
+ trace("< DQT marker\n");
return 0;
}
@@ -513,6 +533,7 @@ static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
int Q_table;
struct component *c;
+ trace("> SOF marker\n");
print_SOF(stream);
height = be16_to_cpu(stream+3);
@@ -521,31 +542,34 @@ static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
#if SANITY_CHECK
if (stream[2] != 8)
error("Precision other than 8 is not supported\n");
- if (width>2048 || height>2048)
+ if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT)
error("Width and Height (%dx%d) seems suspicious\n", width, height);
if (nr_components != 3)
error("We only support YUV images\n");
- if (height%16)
- error("Height need to be a multiple of 16 (current height is %d)\n", height);
- if (width%16)
- error("Width need to be a multiple of 16 (current Width is %d)\n", width);
#endif
stream += 8;
for (i=0; i<nr_components; i++) {
cid = *stream++;
sampling_factor = *stream++;
Q_table = *stream++;
- c = &priv->component_infos[cid];
+ c = &priv->component_infos[i];
+#if SANITY_CHECK
+ c->cid = cid;
+ if (Q_table >= COMPONENTS)
+ error("Bad Quantization table index (got %d, max allowed %d)\n", Q_table, COMPONENTS-1);
+#endif
c->Vfactor = sampling_factor&0xf;
c->Hfactor = sampling_factor>>4;
c->Q_table = priv->Q_tables[Q_table];
trace("Component:%d factor:%dx%d Quantization table:%d\n",
- cid, c->Hfactor, c->Hfactor, Q_table );
+ cid, c->Hfactor, c->Hfactor, Q_table );
}
priv->width = width;
priv->height = height;
+ trace("< SOF marker\n");
+
return 0;
}
@@ -570,12 +594,16 @@ static int parse_SOS(struct jdec_private *priv, const unsigned char *stream)
error("We do not support more than 2 AC Huffman table\n");
if ((table>>4)>=4)
error("We do not support more than 2 DC Huffman table\n");
+ if (cid != priv->component_infos[i].cid)
+ error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n",
+ i, cid, i, priv->component_infos[i].cid);
trace("ComponentId:%d tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);
#endif
- priv->component_infos[cid].AC_table = &priv->HTAC[table&0xf];
- priv->component_infos[cid].DC_table = &priv->HTDC[table>>4];
+ priv->component_infos[i].AC_table = &priv->HTAC[table&0xf];
+ priv->component_infos[i].DC_table = &priv->HTDC[table>>4];
}
priv->stream = stream+3;
+ trace("< SOS marker\n");
return 0;
}
@@ -601,12 +629,11 @@ static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
count += huff_bits[i];
}
#if SANITY_CHECK
- if (count > 1024)
- error("No more than 1024 bytes is allowed to describe a huffman table");
+ if (count >= HUFFMAN_BITS_SIZE)
+ error("No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
if ( (index &0xf) >= HUFFMAN_TABLES)
- error("No mode than %d Huffman tables is supported\n", HUFFMAN_TABLES);
- trace("Huffman table %s n%d\n", (index&0xf0)?"AC":"DC", index&0xf);
- trace("Length of the table: %d\n", count);
+ error("No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index&0xf);
+ trace("Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);
#endif
if (index & 0xf0 )
@@ -617,11 +644,38 @@ static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
length -= 1;
length -= 16;
length -= count;
+ stream += count;
}
trace("< DHT marker\n");
return 0;
}
+static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
+{
+ unsigned int length;
+
+ trace("> DRI marker\n");
+
+ length = be16_to_cpu(stream);
+
+#if SANITY_CHECK
+ if (length != 4)
+ error("Length of DRI marker need to be 4\n");
+#endif
+
+ priv->restart_interval = be16_to_cpu(stream+2);
+
+#if DEBUG
+ trace("Restart interval = %d\n", priv->restart_interval);
+#endif
+
+ trace("< DRI marker\n");
+
+ return 0;
+}
+
+
+
static void resync(struct jdec_private *priv)
{
int i;
@@ -632,9 +686,46 @@ static void resync(struct jdec_private *priv)
priv->reservoir = 0;
priv->nbits_in_reservoir = 0;
-
+ if (priv->restart_interval > 0)
+ priv->restarts_to_go = priv->restart_interval;
+ else
+ priv->restarts_to_go = -1;
}
+static int find_next_rst_marker(struct jdec_private *priv)
+{
+ int rst_marker_found = 0;
+ int marker;
+ const unsigned char *stream = priv->stream;
+
+ /* Parse marker */
+ while (!rst_marker_found)
+ {
+ while (*stream++ != 0xff)
+ {
+ if (stream >= priv->stream_end)
+ error("EOF while search for a RST marker.");
+ }
+ /* Skip any padding ff byte (this is normal) */
+ while (*stream == 0xff)
+ stream++;
+
+ marker = *stream++;
+ if ((RST+priv->last_rst_marker_seen) == marker)
+ rst_marker_found = 1;
+ else if (marker >= RST && marker <= RST7)
+ error("Wrong Reset marker found, abording");
+ else if (marker == EOI)
+ return 0;
+ }
+ trace("RST Marker %d found at offset %d\n", priv->last_rst_marker_seen, stream - priv->stream_begin);
+
+ priv->stream = stream;
+ priv->last_rst_marker_seen++;
+ priv->last_rst_marker_seen &= 7;
+
+ return 0;
+}
static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
{
@@ -676,6 +767,10 @@ static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
return -1;
dht_marker_found = 1;
break;
+ case DRI:
+ if (parse_DRI(priv, stream) < 0)
+ return -1;
+ break;
default:
trace("> Unknown marker %2.2x\n", marker);
break;
@@ -767,6 +862,7 @@ int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, u
priv->stream_begin = buf+2;
priv->stream_length = size-2;
+ priv->stream_end = priv->stream_begin + priv->stream_length;
ret = parse_JFIF(priv, priv->stream_begin);
@@ -781,18 +877,21 @@ int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, u
int tinyjpeg_decode(struct jdec_private *priv,
const struct tinyjpeg_colorspace *pixfmt)
{
- unsigned int x, y, xstride_by_mcu, ystride_by_mcu;
+ int x, y, sx, sy;
+ int xshift_by_mcu, yshift_by_mcu;
+ int xstride_by_mcu, ystride_by_mcu;
unsigned int bytes_per_blocklines[3], bytes_per_mcu[3];
decode_MCU_fct decode_MCU;
const decode_MCU_fct *decode_mcu_table;
convert_colorspace_fct convert_to_pixfmt;
+ uint8_t *pptr[3];
decode_mcu_table = pixfmt->decode_mcu_table;
/* Fix: check return value */
pixfmt->initialize(priv, bytes_per_blocklines, bytes_per_mcu);
- xstride_by_mcu = ystride_by_mcu = 8;
+ xshift_by_mcu = yshift_by_mcu = 3;
if ((priv->component_infos[cY].Hfactor | priv->component_infos[cY].Vfactor) == 1) {
decode_MCU = decode_mcu_table[0];
convert_to_pixfmt = pixfmt->convert_colorspace[0];
@@ -800,55 +899,85 @@ int tinyjpeg_decode(struct jdec_private *priv,
} else if (priv->component_infos[cY].Hfactor == 1) {
decode_MCU = decode_mcu_table[1];
convert_to_pixfmt = pixfmt->convert_colorspace[1];
- ystride_by_mcu = 16;
+ yshift_by_mcu = 4;
trace("Use decode 1x2 sampling (not supported)\n");
} else if (priv->component_infos[cY].Vfactor == 2) {
decode_MCU = decode_mcu_table[3];
convert_to_pixfmt = pixfmt->convert_colorspace[3];
- xstride_by_mcu = 16;
- ystride_by_mcu = 16;
+ xshift_by_mcu = 4;
+ yshift_by_mcu = 4;
trace("Use decode 2x2 sampling\n");
} else {
decode_MCU = decode_mcu_table[2];
convert_to_pixfmt = pixfmt->convert_colorspace[2];
- xstride_by_mcu = 16;
+ xshift_by_mcu = 4;
trace("Use decode 2x1 sampling\n");
}
resync(priv);
/* Don't forget to that block can be either 8 or 16 lines */
- bytes_per_blocklines[0] *= ystride_by_mcu;
- bytes_per_blocklines[1] *= ystride_by_mcu;
- bytes_per_blocklines[2] *= ystride_by_mcu;
+ bytes_per_blocklines[0] <<= yshift_by_mcu-3;
+ bytes_per_blocklines[1] <<= yshift_by_mcu-3;
+ bytes_per_blocklines[2] <<= yshift_by_mcu-3;
+
+ bytes_per_mcu[0] <<= xshift_by_mcu-3;
+ bytes_per_mcu[1] <<= xshift_by_mcu-3;
+ bytes_per_mcu[2] <<= xshift_by_mcu-3;
- bytes_per_mcu[0] *= xstride_by_mcu/8;
- bytes_per_mcu[1] *= xstride_by_mcu/8;
- bytes_per_mcu[2] *= xstride_by_mcu/8;
+ xstride_by_mcu = 1 << xshift_by_mcu;
+ ystride_by_mcu = 1 << yshift_by_mcu;
- /* Just the decode the image by macroblock (size is 8x8, 8x16, or 16x16) */
- for (y=0; y < priv->height/ystride_by_mcu; y++)
+ pptr[0] = priv->components[0];
+ pptr[1] = priv->components[1];
+ pptr[2] = priv->components[2];
+
+ trace("bpbl = %d, bpmcu = %d\n",
+ bytes_per_blocklines[0], bytes_per_mcu[0]);
+
+ for (y = priv->height; y > 0; y -= ystride_by_mcu)
{
- //trace("Decoding row %d\n", y);
- priv->plane[0] = priv->components[0] + (y * bytes_per_blocklines[0]);
- priv->plane[1] = priv->components[1] + (y * bytes_per_blocklines[1]);
- priv->plane[2] = priv->components[2] + (y * bytes_per_blocklines[2]);
- for (x=0; x < priv->width; x+=xstride_by_mcu)
+ trace("Decoding row %d\n", priv->height-y);
+ priv->plane[0] = pptr[0]; pptr[0] += bytes_per_blocklines[0];
+ priv->plane[1] = pptr[1]; pptr[1] += bytes_per_blocklines[1];
+ priv->plane[2] = pptr[2]; pptr[2] += bytes_per_blocklines[2];
+
+ sy = min(y, ystride_by_mcu);
+
+ for (x = priv->width; x > 0; x -= xstride_by_mcu)
{
+ sx = min(x, xstride_by_mcu);
+ trace("Block size: %dx%d\n", sx, sy);
+
decode_MCU(priv);
- convert_to_pixfmt(priv);
+ convert_to_pixfmt(priv, sx, sy);
priv->plane[0] += bytes_per_mcu[0];
priv->plane[1] += bytes_per_mcu[1];
priv->plane[2] += bytes_per_mcu[2];
-
+ if (priv->restarts_to_go>0)
+ {
+ priv->restarts_to_go--;
+ if (priv->restarts_to_go == 0)
+ {
+ priv->stream -= (priv->nbits_in_reservoir/8);
+ resync(priv);
+ if (find_next_rst_marker(priv) < 0)
+ return -1;
+ }
+ }
}
}
+ trace("Input file size: %d\n", priv->stream_length+2);
+ trace("Input bytes actually read: %d\n", priv->stream - priv->stream_begin + 2);
+
return 0;
}
const char *tinyjpeg_get_errorstring(struct jdec_private *priv)
{
+ /* FIXME: the error string must be store in the context */
+ priv = priv;
return error_string;
}
@@ -860,7 +989,7 @@ void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned
int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **components, unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -870,7 +999,7 @@ int tinyjpeg_get_components(struct jdec_private *priv, unsigned char **component
int tinyjpeg_set_components(struct jdec_private *priv, unsigned char * const *components, unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -882,7 +1011,7 @@ int tinyjpeg_get_bytes_per_row(struct jdec_private *priv,
unsigned int *bytes,
unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
@@ -894,7 +1023,7 @@ int tinyjpeg_set_bytes_per_row(struct jdec_private *priv,
const unsigned int *bytes,
unsigned int ncomponents)
{
- int i;
+ unsigned int i;
if (ncomponents > COMPONENTS)
ncomponents = COMPONENTS;
for (i=0; i<ncomponents; i++)
diff --git a/com32/lib/jpeg/yuv420p.c b/com32/lib/jpeg/yuv420p.c
index 0c5edf7c..c512089c 100644
--- a/com32/lib/jpeg/yuv420p.c
+++ b/com32/lib/jpeg/yuv420p.c
@@ -43,13 +43,28 @@
#include "tinyjpeg.h"
#include "tinyjpeg-internal.h"
+/*******************************************************************************
+ *
+ * Colorspace conversion routine
+ *
+ *
+ * Note:
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb
+ *
+ ******************************************************************************/
+
/**
* YCrCb -> YUV420P (1x1)
* .---.
* | 1 |
* `---'
*/
-static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
+static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *s, *y;
unsigned char *p;
@@ -57,19 +72,21 @@ static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
p = priv->plane[0];
y = priv->Y;
- for (i=0; i<8; i++)
+ for (i = sy; i > 0; i--)
{
- memcpy(p, y, 8);
+ memcpy(p, y, sx);
p += priv->bytes_per_row[0];
y += 8;
}
p = priv->plane[1];
s = priv->Cb;
- for (i=0; i<8; i+=2)
+ for (i = sy; i > 0; i--)
{
- for (j=0; j<8; j+=2, s+=2)
+ for (j = sx; j >= 0; j -= 2) {
*p++ = *s;
+ s += 2;
+ }
s += 8; /* Skip one line */
p += priv->bytes_per_row[1] - 4;
}
@@ -78,8 +95,10 @@ static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
s = priv->Cr;
for (i=0; i<8; i+=2)
{
- for (j=0; j<8; j+=2, s+=2)
+ for (j = sx; j >= 0; j -= 2) {
*p++ = *s;
+ s += 2;
+ }
s += 8; /* Skip one line */
p += priv->bytes_per_row[2] - 4;
}
@@ -91,39 +110,39 @@ static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv)
* | 1 | 2 |
* `-------'
*/
-static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
+static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv, int sx, int sy)
{
unsigned char *p;
const unsigned char *s, *y1;
- int i,j;
+ unsigned int i;
p = priv->plane[0];
y1 = priv->Y;
- for (i=0; i<8; i++)
+ for (i = sy; i > 0; i--)
{
- memcpy(p, y1, 16);
+ memcpy(p, y1, sx);
p += priv->bytes_per_row[0];
y1 += 16;
}
+ sx = (sx+1) >> 1;
+
p = priv->plane[1];
s = priv->Cb;
- for (i=0; i<8; i+=2)
+ for (i = sy; i > 0; i -= 2)
{
- for (j=0; j<8; j+=1, s+=1)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->bytes_per_row[1] - 8;
+ memcpy(p, s, sx);
+ s += 16; /* Skip one line */
+ p += priv->bytes_per_row[1];
}
p = priv->plane[2];
s = priv->Cr;
- for (i=0; i<8; i+=2)
+ for (i = sy; i > 0; i -= 2)
{
- for (j=0; j<8; j+=1, s+=1)
- *p++ = *s;
- s += 8; /* Skip one line */
- p += priv->bytes_per_row[2] - 8;
+ memcpy(p, s, sx);
+ s += 16; /* Skip one line */
+ p += priv->bytes_per_row[2];
}
}
@@ -136,37 +155,43 @@ static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv)
* | 2 |
* `---'
*/
-static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv)
+static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv, int sx, int sy)
{
const unsigned char *s, *y;
- unsigned char *p;
+ unsigned char *p, *pr;
int i,j;
p = priv->plane[0];
y = priv->Y;
- for (i=0; i<16; i++)
+ for (i = sy; i > 0; i++)
{
- memcpy(p, y, 8);
+ memcpy(p, y, sx);
p+=priv->bytes_per_row[0];
y+=8;
}
- p = priv->plane[1];
+ pr = priv->plane[1];
s = priv->Cb;
- for (i=0; i<8; i++)
+ for (i = sy; i > 0; i -= 2)
{
- for (j=0; j<8; j+=2, s+=2)
+ p = pr;
+ for (j = sx; j > 0; j -= 2) {
*p++ = *s;
- p += priv->bytes_per_row[1] - 4;
+ s += 2;
+ }
+ pr += priv->bytes_per_row[1];
}
- p = priv->plane[2];
+ pr = priv->plane[2];
s = priv->Cr;
for (i=0; i<8; i++)
{
- for (j=0; j<8; j+=2, s+=2)
+ p = pr;
+ for (j = sx; j > 0; j -= 2) {
*p++ = *s;
- p += priv->bytes_per_row[2] - 4;
+ s += 2;
+ }
+ pr += priv->bytes_per_row[2] - 4;
}
}
@@ -178,35 +203,37 @@ static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv)
* | 3 | 4 |
* `-------'
*/
-static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv)
+static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv, int sx, int sy)
{
unsigned char *p;
const unsigned char *s, *y1;
- int i;
+ unsigned int i;
p = priv->plane[0];
y1 = priv->Y;
- for (i=0; i<16; i++)
+ for (i = sy; i > 0; i--)
{
- memcpy(p, y1, 16);
+ memcpy(p, y1, sx);
p += priv->bytes_per_row[0];
y1 += 16;
}
+ sx = (sx+1) >> 1;
+
p = priv->plane[1];
s = priv->Cb;
- for (i=0; i<8; i++)
+ for (i = sy; i > 0; i -= 2)
{
- memcpy(p, s, 8);
+ memcpy(p, s, sx);
s += 8;
p += priv->bytes_per_row[1];
}
p = priv->plane[2];
s = priv->Cr;
- for (i=0; i<8; i++)
+ for (i = sy; i > 0; i -= 2)
{
- memcpy(p, s, 8);
+ memcpy(p, s, sx);
s += 8;
p += priv->bytes_per_row[2];
}
@@ -216,26 +243,32 @@ static int initialize_yuv420p(struct jdec_private *priv,
unsigned int *bytes_per_blocklines,
unsigned int *bytes_per_mcu)
{
- if (priv->components[0] == NULL)
- priv->components[0] = (uint8_t *)malloc(priv->width * priv->height);
- if (priv->components[1] == NULL)
- priv->components[1] = (uint8_t *)malloc(priv->width * priv->height/4);
- if (priv->components[2] == NULL)
- priv->components[2] = (uint8_t *)malloc(priv->width * priv->height/4);
+ int half_height = (priv->height + 1) >> 2;
+ int half_width = (priv->width + 1) >> 2;
+
if (!priv->bytes_per_row[0])
priv->bytes_per_row[0] = priv->width;
+ if (!priv->components[0])
+ priv->components[0] = malloc(priv->height * priv->bytes_per_row[0]);
+
if (!priv->bytes_per_row[1])
- priv->bytes_per_row[1] = priv->width/2;
+ priv->bytes_per_row[1] = half_width;
+ if (!priv->components[1])
+ priv->components[1] = malloc(half_height * priv->bytes_per_row[1]);
+
if (!priv->bytes_per_row[2])
- priv->bytes_per_row[2] = priv->width/2;
+ priv->bytes_per_row[2] = half_width;
+ if (!priv->components[2])
+ priv->components[2] = malloc(half_height * priv->bytes_per_row[2]);
- bytes_per_blocklines[0] = priv->bytes_per_row[0];
- bytes_per_blocklines[1] = priv->bytes_per_row[1]/2;
- bytes_per_blocklines[2] = priv->bytes_per_row[2]/2;
bytes_per_mcu[0] = 8;
bytes_per_mcu[1] = 4;
bytes_per_mcu[2] = 4;
+ bytes_per_blocklines[0] = priv->width << 3;
+ bytes_per_blocklines[1] = half_width << 2;
+ bytes_per_blocklines[2] = half_width << 2;
+
/* Return nonzero on failure */
return !priv->components[0] || !priv->components[1] || !priv->components[2];
}
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index 815f984c..256c8247 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -44,9 +44,9 @@
aligned dwords. */
static void draw_background_line(int line, int start, int npixels)
{
- uint32_t *bgptr = &__vesacon_background[line][start];
+ uint32_t *bgptr = &__vesacon_background[line*__vesa_info.mi.h_res+start];
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
- size_t fbptr = line * __vesa_info.mi.logical_scan + start * bytes_per_pixel;
+ size_t fbptr = line * __vesa_info.mi.logical_scan + start*bytes_per_pixel;
__vesacon_copy_to_screen(fbptr, bgptr, npixels);
}
@@ -60,15 +60,17 @@ static void draw_background(void)
const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH);
for (i = 0; i < VIDEO_BORDER; i++)
- draw_background_line(i, 0, VIDEO_X_SIZE);
+ draw_background_line(i, 0, __vesa_info.mi.h_res);
- for (i = VIDEO_BORDER; i < VIDEO_Y_SIZE - bottom_border; i++) {
+ for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) {
draw_background_line(i, 0, VIDEO_BORDER);
- draw_background_line(i, VIDEO_X_SIZE - right_border, right_border);
+ draw_background_line(i, __vesa_info.mi.h_res - right_border,
+ right_border);
}
- for (i = VIDEO_Y_SIZE - bottom_border; i < VIDEO_Y_SIZE; i++)
- draw_background_line(i, 0, VIDEO_X_SIZE);
+ for (i = __vesa_info.mi.v_res - bottom_border;
+ i < __vesa_info.mi.v_res; i++)
+ draw_background_line(i, 0, __vesa_info.mi.h_res);
__vesacon_redraw_text();
}
@@ -82,7 +84,7 @@ static int read_png_file(FILE * fp)
png_color_16p image_background;
static const png_color_16 my_background = { 0, 0, 0, 0, 0 };
#endif
- png_bytep row_pointers[VIDEO_Y_SIZE];
+ png_bytep row_pointers[__vesa_info.mi.v_res], rp;
int passes;
int i;
int rv = -1;
@@ -98,7 +100,7 @@ static int read_png_file(FILE * fp)
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
- png_set_user_limits(png_ptr, VIDEO_X_SIZE, VIDEO_Y_SIZE);
+ png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res);
png_read_info(png_ptr, info_ptr);
@@ -138,8 +140,11 @@ static int read_png_file(FILE * fp)
#endif
/* Whew! Now we should get the stuff we want... */
- for (i = 0; i < (int)info_ptr->height; i++)
- row_pointers[i] = (void *)__vesacon_background[i];
+ rp = (png_bytep)__vesacon_background;
+ for (i = 0; i < (int)info_ptr->height; i++) {
+ row_pointers[i] = rp;
+ rp += __vesa_info.mi.h_res << 2;
+ }
passes = png_set_interlace_handling(png_ptr);
@@ -157,6 +162,7 @@ err:
static int jpeg_sig_cmp(uint8_t * bytes, int len)
{
(void)len;
+
return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1;
}
@@ -183,12 +189,12 @@ static int read_jpeg_file(FILE * fp, uint8_t * header, int len)
goto err;
tinyjpeg_get_size(jdec, &width, &height);
- if (width > VIDEO_X_SIZE || height > VIDEO_Y_SIZE)
+ if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res)
goto err;
- components[0] = (void *)&__vesacon_background[0];
+ components[0] = (void *)__vesacon_background;
tinyjpeg_set_components(jdec, components, 1);
- bytes_per_row[0] = VIDEO_X_SIZE << 2;
+ bytes_per_row[0] = __vesa_info.mi.h_res << 2;
tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1);
tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32);
@@ -217,9 +223,11 @@ int vesacon_default_background(void)
if (__vesacon_pixel_format == PXF_NONE)
return 0; /* Not in graphics mode */
- for (y = 0, dy = -VIDEO_Y_SIZE / 2; y < VIDEO_Y_SIZE; y++, dy++) {
+ for (y = 0, dy = -__vesa_info.mi.v_res / 2;
+ y < __vesa_info.mi.v_res; y++, dy++) {
dy2 = dy * dy;
- for (x = 0, dx = -VIDEO_X_SIZE / 2; x < VIDEO_X_SIZE; x++, dx++) {
+ for (x = 0, dx = -__vesa_info.mi.h_res / 2;
+ x < __vesa_info.mi.h_res; x++, dx++) {
k = __vesacon_linear_to_srgb[500 + ((dx * dx + dy2) >> 6)];
bgptr[0] = k; /* Blue */
bgptr[1] = k; /* Green */
@@ -236,7 +244,7 @@ int vesacon_default_background(void)
int vesacon_set_background(unsigned int rgb)
{
void *bgptr = __vesacon_background;
- unsigned int count = VIDEO_X_SIZE * VIDEO_Y_SIZE;
+ unsigned int count = __vesa_info.mi.h_res * __vesa_info.mi.v_res;
if (__vesacon_pixel_format == PXF_NONE)
return 0; /* Not in graphics mode */
@@ -265,7 +273,8 @@ static inline int lss16_sig_cmp(const void *header, int len)
return 1;
return !(h->magic == LSS16_MAGIC &&
- h->xsize <= VIDEO_X_SIZE && h->ysize <= VIDEO_Y_SIZE);
+ h->xsize <= __vesa_info.mi.h_res &&
+ h->ysize <= __vesa_info.mi.v_res);
}
static int read_lss16_file(FILE * fp, const void *header, int header_len)
@@ -283,7 +292,7 @@ static int read_lss16_file(FILE * fp, const void *header, int header_len)
st_c2,
} state;
int i, x, y;
- uint32_t *bgptr = (void *)__vesacon_background;
+ uint32_t *bgptr = __vesacon_background;
/* Assume the header, 8 bytes, has already been loaded. */
if (header_len != 8)
@@ -295,7 +304,8 @@ static int read_lss16_file(FILE * fp, const void *header, int header_len)
return -1;
colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) +
- (((rgb[1] & 63) * 255 / 63) << 8) + ((rgb[2] & 63) * 255 / 63);
+ (((rgb[1] & 63) * 255 / 63) << 8) +
+ ((rgb[2] & 63) * 255 / 63);
}
/* By spec, the state machine is per row */
@@ -356,12 +366,12 @@ do_run:
}
/* Zero-fill rest of row */
- i = VIDEO_X_SIZE - x;
+ i = __vesa_info.mi.h_res - x;
asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
}
/* Zero-fill rest of screen */
- i = (VIDEO_Y_SIZE - y) * VIDEO_X_SIZE;
+ i = (__vesa_info.mi.v_res - y) * __vesa_info.mi.h_res;
asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory");
return 0;
@@ -404,7 +414,7 @@ err:
int __vesacon_init_background(void)
{
- /* The BSS clearing has already cleared __vesacon_background */
+ /* __vesacon_background was cleared by calloc() */
/* The VESA BIOS has already cleared the screen */
return 0;
diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c
index 4b46d678..92d89018 100644
--- a/com32/lib/sys/vesa/drawtxt.c
+++ b/com32/lib/sys/vesa/drawtxt.c
@@ -27,6 +27,7 @@
#include <inttypes.h>
#include <colortbl.h>
+#include <string.h>
#include "vesa.h"
#include "video.h"
#include "fill.h"
@@ -81,25 +82,20 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
unsigned long pixel_offset;
- uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr;
+ uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr;
size_t fbrowptr;
uint8_t sha;
- bgrowptr =
- &__vesacon_background[row * height + VIDEO_BORDER][col * width +
- VIDEO_BORDER];
-
- pixel_offset = ((row * height + VIDEO_BORDER) * VIDEO_X_SIZE) +
+ pixel_offset = ((row * height + VIDEO_BORDER) * __vesa_info.mi.h_res) +
(col * width + VIDEO_BORDER);
+ bgrowptr = &__vesacon_background[pixel_offset];
fbrowptr = (row * height + VIDEO_BORDER) * __vesa_info.mi.logical_scan +
(col * width + VIDEO_BORDER) * bytes_per_pixel;
/* Note that we keep a 1-character guard area around the real text area... */
- rowptr =
- &__vesacon_text_display[(row + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) +
- (col + 1)];
- rowsptr = rowptr - ((TEXT_PIXEL_COLS / FONT_WIDTH + 2) + 1);
+ rowptr = &__vesacon_text_display[(row+1)*(__vesacon_text_cols+2)+(col+1)];
+ rowsptr = rowptr - ((__vesacon_text_cols+2)+1);
pixrow = 0;
pixsrow = height - 1;
@@ -159,7 +155,8 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
}
/* If this pixel is raised, use the offsetted value */
- bgval = (chxbits & 0x80) ? bgptr[VIDEO_X_SIZE + 1] : *bgptr;
+ bgval = (chxbits & 0x80)
+ ? bgptr[__vesa_info.mi.h_res + 1] : *bgptr;
bgptr++;
/* If this pixel is set, use the fg color, else the bg color */
@@ -180,15 +177,15 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
/* Copy to frame buffer */
__vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer);
- bgrowptr += VIDEO_X_SIZE;
+ bgrowptr += __vesa_info.mi.h_res;
fbrowptr += __vesa_info.mi.logical_scan;
if (++pixrow == height) {
- rowptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ rowptr += __vesacon_text_cols + 2;
pixrow = 0;
}
if (++pixsrow == height) {
- rowsptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ rowsptr += __vesacon_text_cols + 2;
pixsrow = 0;
}
}
@@ -232,7 +229,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
{
int y;
struct vesa_char *ptr = &__vesacon_text_display
- [(y0 + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x0 + 1)];
+ [(y0 + 1) * (__vesacon_text_cols + 2) + (x0 + 1)];
struct vesa_char fill = {
.ch = ' ',
.attr = attr,
@@ -241,7 +238,7 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
for (y = y0; y <= y1; y++) {
vesacon_fill(ptr, fill, ncols);
- ptr += TEXT_PIXEL_COLS / FONT_WIDTH + 2;
+ ptr += __vesacon_text_cols + 2;
}
vesacon_touch(y0, x0, y1 - y0 + 1, ncols);
@@ -251,11 +248,11 @@ void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr)
void __vesacon_scroll_up(int nrows, attr_t attr)
{
struct vesa_char *fromptr = &__vesacon_text_display
- [(nrows + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2)];
+ [(nrows + 1) * (__vesacon_text_cols + 2)];
struct vesa_char *toptr = &__vesacon_text_display
- [(TEXT_PIXEL_COLS / FONT_WIDTH + 2)];
+ [(__vesacon_text_cols + 2)];
int dword_count =
- (__vesacon_text_rows - nrows) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ (__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2);
struct vesa_char fill = {
.ch = ' ',
.attr = attr,
@@ -263,18 +260,18 @@ void __vesacon_scroll_up(int nrows, attr_t attr)
toptr = copy_dword(toptr, fromptr, dword_count);
- dword_count = nrows * (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ dword_count = nrows * (__vesacon_text_cols + 2);
vesacon_fill(toptr, fill, dword_count);
- vesacon_touch(0, 0, __vesacon_text_rows, TEXT_PIXEL_COLS / FONT_WIDTH);
+ vesacon_touch(0, 0, __vesacon_text_rows, __vesacon_text_cols);
}
/* Draw one character text at a specific area of the screen */
void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr)
{
struct vesa_char *ptr = &__vesacon_text_display
- [(y + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x + 1)];
+ [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
ptr->ch = ch;
ptr->attr = attr;
@@ -285,7 +282,7 @@ void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr)
void __vesacon_set_cursor(int x, int y, int visible)
{
struct vesa_char *ptr = &__vesacon_text_display
- [(y + 1) * (TEXT_PIXEL_COLS / FONT_WIDTH + 2) + (x + 1)];
+ [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)];
if (cursor_pointer)
vesacon_touch(cursor_y, cursor_x, 1, 1);
@@ -309,13 +306,12 @@ void __vesacon_init_cursor(int font_height)
if (r0 < 0)
r0 = 0;
- /* cursor_pattern is assumed to be all zero */
+ memset(cursor_pattern, 0, font_height);
cursor_pattern[r0] = 0xff;
cursor_pattern[r0 + 1] = 0xff;
}
void __vesacon_redraw_text(void)
{
- vesacon_update_characters(0, 0, __vesacon_text_rows,
- TEXT_PIXEL_COLS / FONT_WIDTH);
+ vesacon_update_characters(0, 0, __vesacon_text_rows, __vesacon_text_cols);
}
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index 9254683b..0221fcf7 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -46,12 +46,14 @@ struct vesa_info __vesa_info;
struct vesa_char *__vesacon_text_display;
-int __vesacon_font_height, __vesacon_text_rows;
+int __vesacon_font_height;
+int __vesacon_text_rows;
+int __vesacon_text_cols;
enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE;
unsigned int __vesacon_bytes_per_pixel;
uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
-uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE];
+uint32_t *__vesacon_background, *__vesacon_shadowfb;
static void unpack_font(uint8_t * dst, uint8_t * src, int height)
{
@@ -87,7 +89,7 @@ static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi)
return 0; /* Nope... */
}
-static int vesacon_set_mode(void)
+static int vesacon_set_mode(int x, int y)
{
com32sys_t rm;
uint8_t *rom_font;
@@ -96,6 +98,16 @@ static int vesacon_set_mode(void)
struct vesa_mode_info *mi;
enum vesa_pixel_format pxf, bestpxf;
+ /* Free any existing data structures */
+ if (__vesacon_background) {
+ free(__vesacon_background);
+ __vesacon_background = NULL;
+ }
+ if (__vesacon_shadowfb) {
+ free(__vesacon_shadowfb);
+ __vesacon_shadowfb = NULL;
+ }
+
/* Allocate space in the bounce buffer for these structures */
gi = &((struct vesa_info *)__com32.cs_bounce)->gi;
mi = &((struct vesa_info *)__com32.cs_bounce)->mi;
@@ -121,7 +133,7 @@ static int vesacon_set_mode(void)
/* Copy general info */
memcpy(&__vesa_info.gi, gi, sizeof *gi);
- /* Search for a 640x480 mode with a suitable color and memory model... */
+ /* Search for the proper mode with a suitable color and memory model... */
mode_ptr = GET_PTR(gi->video_mode_ptr);
bestmode = 0;
@@ -159,8 +171,8 @@ static int vesacon_set_mode(void)
if ((mi->mode_attr & 0x001b) != 0x001b)
continue;
- /* Must be 640x480 */
- if (mi->h_res != VIDEO_X_SIZE || mi->v_res != VIDEO_Y_SIZE)
+ /* Must be the chosen size */
+ if (mi->h_res != x || mi->v_res != y)
continue;
/* We don't support multibank (interlaced memory) modes */
@@ -242,9 +254,6 @@ static int vesacon_set_mode(void)
}
unpack_font((uint8_t *) __vesacon_graphics_font, rom_font,
__vesacon_font_height);
- __vesacon_text_rows =
- (VIDEO_Y_SIZE - 2 * VIDEO_BORDER) / __vesacon_font_height;
- __vesacon_init_cursor(__vesacon_font_height);
/* Now set video mode */
rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */
@@ -255,6 +264,9 @@ static int vesacon_set_mode(void)
if (rm.eax.w[0] != 0x004F)
return 9; /* Failed to set mode */
+ __vesacon_background = calloc(mi->h_res*mi->v_res, 4);
+ __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4);
+
__vesacon_init_copy_to_screen();
/* Tell syslinux we changed video mode */
@@ -266,8 +278,8 @@ static int vesacon_set_mode(void)
However, that would assume all systems that claim to handle text
output in VESA modes actually do that... */
rm.ebx.w[0] = 0x000f;
- rm.ecx.w[0] = VIDEO_X_SIZE;
- rm.edx.w[0] = VIDEO_Y_SIZE;
+ rm.ecx.w[0] = mi->h_res;
+ rm.edx.w[0] = mi->v_res;
__intcall(0x22, &rm, NULL);
__vesacon_pixel_format = bestpxf;
@@ -284,8 +296,12 @@ static int init_text_display(void)
.attr = 0,
};
- nchars = (TEXT_PIXEL_ROWS / __vesacon_font_height + 2) *
- (TEXT_PIXEL_COLS / FONT_WIDTH + 2);
+ if (__vesacon_text_display)
+ free(__vesacon_text_display);
+
+ __vesacon_text_cols = TEXT_PIXEL_COLS / FONT_WIDTH;
+ __vesacon_text_rows = TEXT_PIXEL_ROWS / __vesacon_font_height;
+ nchars = (__vesacon_text_cols+2) * (__vesacon_text_rows+2);
__vesacon_text_display = ptr = malloc(nchars * sizeof(struct vesa_char));
@@ -293,11 +309,12 @@ static int init_text_display(void)
return -1;
vesacon_fill(ptr, def_char, nchars);
+ __vesacon_init_cursor(__vesacon_font_height);
return 0;
}
-int __vesacon_init(void)
+int __vesacon_init(int x, int y)
{
int rv;
@@ -305,7 +322,7 @@ int __vesacon_init(void)
if (x86_init_fpu())
return 10;
- rv = vesacon_set_mode();
+ rv = vesacon_set_mode(x, y);
if (rv)
return rv;
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index b02b5ae7..0bd1abff 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -29,17 +29,18 @@
#define LIB_SYS_VESA_VIDEO_H
#include <colortbl.h>
+#include "vesa.h"
#define FONT_MAX_CHARS 256
#define FONT_MAX_HEIGHT 32
#define FONT_WIDTH 8
-#define VIDEO_X_SIZE 640
-#define VIDEO_Y_SIZE 480
+#define DEFAULT_VESA_X_SIZE 640
+#define DEFAULT_VESA_Y_SIZE 480
#define VIDEO_BORDER 8
-#define TEXT_PIXEL_ROWS (VIDEO_Y_SIZE-2*VIDEO_BORDER)
-#define TEXT_PIXEL_COLS (VIDEO_X_SIZE-2*VIDEO_BORDER)
+#define TEXT_PIXEL_ROWS (__vesa_info.mi.v_res - 2*VIDEO_BORDER)
+#define TEXT_PIXEL_COLS (__vesa_info.mi.h_res - 2*VIDEO_BORDER)
typedef uint16_t attr_t;
@@ -60,24 +61,26 @@ enum vesa_pixel_format {
};
extern enum vesa_pixel_format __vesacon_pixel_format;
extern unsigned int __vesacon_bytes_per_pixel;
-typedef const void *(*__vesacon_format_pixels_t) (void *, const uint32_t *,
- size_t);
+typedef const void *(*__vesacon_format_pixels_t)
+ (void *, const uint32_t *, size_t);
extern __vesacon_format_pixels_t __vesacon_format_pixels;
extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE];
extern struct vesa_char *__vesacon_text_display;
-extern int __vesacon_font_height, __vesacon_text_rows;
+extern int __vesacon_font_height;
+extern int __vesacon_text_rows;
+extern int __vesacon_text_cols;
extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
-extern uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE];
-extern uint32_t __vesacon_shadowfb[VIDEO_Y_SIZE][VIDEO_X_SIZE];
+extern uint32_t *__vesacon_background;
+extern uint32_t *__vesacon_shadowfb;
extern const uint16_t __vesacon_srgb_to_linear[256];
extern const uint8_t __vesacon_linear_to_srgb[4080];
int __vesacon_init_background(void);
int vesacon_load_background(const char *);
-int __vesacon_init(void);
+int __vesacon_init(int, int);
void __vesacon_init_cursor(int);
void __vesacon_erase(int, int, int, int, attr_t);
void __vesacon_scroll_up(int, attr_t);
diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c
index f0fc845f..e85aba88 100644
--- a/com32/lib/sys/vesacon_write.c
+++ b/com32/lib/sys/vesacon_write.c
@@ -61,7 +61,6 @@ static struct ansi_ops op = {
};
static struct term_info ti = {
- .cols = TEXT_PIXEL_COLS / FONT_WIDTH,
.disabled = 0,
.ts = &ts,
.op = &op
@@ -71,6 +70,20 @@ static struct term_info ti = {
reinitialization. */
static int vesacon_counter = 0;
+static struct {
+ int x, y;
+} vesacon_resolution = {
+ .x = DEFAULT_VESA_X_SIZE,
+ .y = DEFAULT_VESA_Y_SIZE,
+};
+
+/* Set desired resolution - requires a full close/open cycle */
+void vesacon_set_resolution(int x, int y)
+{
+ vesacon_resolution.x = x;
+ vesacon_resolution.y = y;
+}
+
/* Common setup */
int __vesacon_open(struct file_info *fp)
{
@@ -84,7 +97,7 @@ int __vesacon_open(struct file_info *fp)
ti.cols = 80;
} else {
/* Switch mode */
- if (__vesacon_init()) {
+ if (__vesacon_init(vesacon_resolution.x, vesacon_resolution.y)) {
vesacon_counter = -1;
return EAGAIN;
}
@@ -92,6 +105,7 @@ int __vesacon_open(struct file_info *fp)
/* Initial state */
__ansi_init(&ti);
ti.rows = __vesacon_text_rows;
+ ti.cols = __vesacon_text_cols;
}
} else if (vesacon_counter == -1) {
return EAGAIN;
diff --git a/com32/menu/menu.c b/com32/menu/menu.c
index 2c069fbe..797189b4 100644
--- a/com32/menu/menu.c
+++ b/com32/menu/menu.c
@@ -27,8 +27,13 @@ int draw_background(const char *arg)
return 0;
}
-int main(int argc, char *argv[])
+void set_resolution(int x, int y)
+{
+ (void)x;
+ (void)y;
+}
+
+void start_console(void)
{
console_ansi_raw();
- return menu_main(argc, argv);
}
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index 3be3ba01..72f5c99e 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -184,6 +184,8 @@ extern long long totaltimeout;
void parse_configs(char **argv);
int draw_background(const char *filename);
+void set_resolution(int x, int y);
+void start_console(void);
static inline int my_isspace(char c)
{
@@ -195,10 +197,6 @@ unsigned int hexval(char c);
unsigned int hexval2(const char *p);
uint32_t parse_argb(char **p);
-int menu_main(int argc, char *argv[]);
-void console_prepare(void);
-void console_cleanup(void);
-
extern const int message_base_color, menu_color_table_size;
int mygetkey(clock_t timeout);
int show_message_file(const char *filename, const char *background);
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index f3f0154b..32ed1b08 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -1072,7 +1072,7 @@ static const char *run_menu(void)
return cmdline;
}
-int menu_main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
const char *cmdline;
struct menu *m;
@@ -1081,14 +1081,20 @@ int menu_main(int argc, char *argv[])
(void)argc;
+ parse_configs(argv + 1);
+
+ /*
+ * We don't start the console until we have parsed the configuration
+ * file, since the configuration file might impact the console
+ * configuration, e.g. MENU RESOLUTION.
+ */
+ start_console();
if (getscreensize(1, &rows, &cols)) {
/* Unknown screen size? */
rows = 24;
cols = 80;
}
- parse_configs(argv + 1);
-
/* Some postprocessing for all menus */
for (m = menu_list; m; m = m->next) {
if (!m->mparm[P_WIDTH])
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 135769e1..a248721e 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -818,6 +818,11 @@ static void parse_config_file(FILE * f)
}
} else if (looking_at(p, "start")) {
start_menu = m;
+ } else if ((ep = looking_at(p, "resolution"))) {
+ int x, y;
+ x = strtoul(ep, &ep, 0);
+ y = strtoul(skipspace(ep), NULL, 0);
+ set_resolution(x, y);
} else {
/* Unknown, check for layout parameters */
enum parameter_number mp;
diff --git a/com32/menu/vesamenu.c b/com32/menu/vesamenu.c
index df5c94a6..22b46235 100644
--- a/com32/menu/vesamenu.c
+++ b/com32/menu/vesamenu.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,8 +36,12 @@ int draw_background(const char *what)
return vesacon_load_background(what);
}
-int main(int argc, char *argv[])
+void set_resolution(int x, int y)
+{
+ vesacon_set_resolution(x, y);
+}
+
+void start_console(void)
{
openconsole(&dev_rawcon_r, &dev_vesaserial_w);
- return menu_main(argc, argv);
}