[SeaBIOS] [PATCH 1/5] Avoid using BSS variables in jpeg.c.

Kevin O'Connor kevin at koconnor.net
Fri Jul 30 20:14:55 CEST 2010


Using BSS increases the rom size (and reduce space for option roms).
So, move BSS variables in the jpeg.c code to malloc'd memory.

Also, move struct and error declarations from jpeg.h to jpeg.c.
---
 src/bootsplash.c |    2 +-
 src/jpeg.c       |  283 +++++++++++++++++++++++++++++-------------------------
 src/jpeg.h       |   36 +------
 3 files changed, 158 insertions(+), 163 deletions(-)

diff --git a/src/bootsplash.c b/src/bootsplash.c
index ed10415..2c45406 100644
--- a/src/bootsplash.c
+++ b/src/bootsplash.c
@@ -127,7 +127,7 @@ void enable_vga_console(void)
     picture = malloc_tmphigh(imagesize);
     vesa_info = malloc_tmplow(sizeof(*vesa_info));
     mode_info = malloc_tmplow(sizeof(*mode_info));
-    decdata = malloc_tmphigh(sizeof(*decdata));
+    decdata = jpeg_alloc();
     if (!jpeg || !picture || !vesa_info || !mode_info || !decdata) {
         warn_noalloc();
         goto gotext;
diff --git a/src/jpeg.c b/src/jpeg.c
index 711f810..b204345 100644
--- a/src/jpeg.c
+++ b/src/jpeg.c
@@ -97,11 +97,9 @@ struct dec_hufftbl {
     unsigned int llvals[1 << DECBITS];
 };
 
-static void decode_mcus
-__P((struct in *, int *, int, struct scan *, int *));
+static void decode_mcus __P((struct in *, int *, int, struct scan *, int *));
 static int dec_readmarker __P((struct in *));
-static void dec_makehuff
-__P((struct dec_hufftbl *, int *, unsigned char *));
+static void dec_makehuff __P((struct dec_hufftbl *, int *, unsigned char *));
 
 static void setinput __P((struct in *, unsigned char *));
 /*********************************/
@@ -123,6 +121,24 @@ static void col221111_32 __P((int *, unsigned char *, int));
 
 /*********************************/
 
+#define ERR_NO_SOI 1
+#define ERR_NOT_8BIT 2
+#define ERR_HEIGHT_MISMATCH 3
+#define ERR_WIDTH_MISMATCH 4
+#define ERR_BAD_WIDTH_OR_HEIGHT 5
+#define ERR_TOO_MANY_COMPPS 6
+#define ERR_ILLEGAL_HV 7
+#define ERR_QUANT_TABLE_SELECTOR 8
+#define ERR_NOT_YCBCR_221111 9
+#define ERR_UNKNOWN_CID_IN_SCAN 10
+#define ERR_NOT_SEQUENTIAL_DCT 11
+#define ERR_WRONG_MARKER 12
+#define ERR_NO_EOI 13
+#define ERR_BAD_TABLES 14
+#define ERR_DEPTH_MISMATCH 15
+
+/*********************************/
+
 #define M_SOI   0xd8
 #define M_APP0  0xe0
 #define M_DQT   0xdb
@@ -134,21 +150,6 @@ static void col221111_32 __P((int *, unsigned char *, int));
 #define M_EOI   0xd9
 #define M_COM   0xfe
 
-static unsigned char *datap;
-
-static int getbyte(void)
-{
-    return *datap++;
-}
-
-static int getword(void)
-{
-    int c1, c2;
-    c1 = *datap++;
-    c2 = *datap++;
-    return c1 << 8 | c2;
-}
-
 struct comp {
     int cid;
     int hv;
@@ -164,29 +165,42 @@ struct jpginfo {
     int rm;   /* next restart marker */
 };
 
-static struct jpginfo info;
-static struct comp comps[MAXCOMP];
-
-static struct scan dscans[MAXCOMP];
-
-static unsigned char quant[4][64];
-
-static struct dec_hufftbl dhuff[4];
+struct jpeg_decdata {
+    int dcts[6 * 64 + 16];
+    int out[64 * 6];
+    int dquant[3][64];
+
+    unsigned char *datap;
+    struct jpginfo info;
+    struct comp comps[MAXCOMP];
+    struct scan dscans[MAXCOMP];
+    unsigned char quant[4][64];
+    struct dec_hufftbl dhuff[4];
+    struct in in;
+};
 
-#define dec_huffdc (dhuff + 0)
-#define dec_huffac (dhuff + 2)
+static int getbyte(struct jpeg_decdata *jpeg)
+{
+    return *jpeg->datap++;
+}
 
-static struct in in;
+static int getword(struct jpeg_decdata *jpeg)
+{
+    int c1, c2;
+    c1 = *jpeg->datap++;
+    c2 = *jpeg->datap++;
+    return c1 << 8 | c2;
+}
 
-static int readtables(int till)
+static int readtables(struct jpeg_decdata *jpeg, int till)
 {
     int m, l, i, j, lq, pq, tq;
     int tc, th, tt;
 
     for (;;) {
-        if (getbyte() != 0xff)
+        if (getbyte(jpeg) != 0xff)
             return -1;
-        if ((m = getbyte()) == till)
+        if ((m = getbyte(jpeg)) == till)
             break;
 
         switch (m) {
@@ -194,9 +208,9 @@ static int readtables(int till)
             return 0;
 
         case M_DQT:
-            lq = getword();
+            lq = getword(jpeg);
             while (lq > 2) {
-                pq = getbyte();
+                pq = getbyte(jpeg);
                 tq = pq & 15;
                 if (tq > 3)
                     return -1;
@@ -204,176 +218,184 @@ static int readtables(int till)
                 if (pq != 0)
                     return -1;
                 for (i = 0; i < 64; i++)
-                    quant[tq][i] = getbyte();
+                    jpeg->quant[tq][i] = getbyte(jpeg);
                 lq -= 64 + 1;
             }
             break;
 
         case M_DHT:
-            l = getword();
+            l = getword(jpeg);
             while (l > 2) {
                 int hufflen[16], k;
                 unsigned char huffvals[256];
 
-                tc = getbyte();
+                tc = getbyte(jpeg);
                 th = tc & 15;
                 tc >>= 4;
                 tt = tc * 2 + th;
                 if (tc > 1 || th > 1)
                     return -1;
                 for (i = 0; i < 16; i++)
-                    hufflen[i] = getbyte();
+                    hufflen[i] = getbyte(jpeg);
                 l -= 1 + 16;
                 k = 0;
                 for (i = 0; i < 16; i++) {
                     for (j = 0; j < hufflen[i]; j++)
-                        huffvals[k++] = getbyte();
+                        huffvals[k++] = getbyte(jpeg);
                     l -= hufflen[i];
                 }
-                dec_makehuff(dhuff + tt, hufflen, huffvals);
+                dec_makehuff(jpeg->dhuff + tt, hufflen, huffvals);
             }
             break;
 
         case M_DRI:
-            l = getword();
-            info.dri = getword();
+            l = getword(jpeg);
+            jpeg->info.dri = getword(jpeg);
             break;
 
         default:
-            l = getword();
+            l = getword(jpeg);
             while (l-- > 2)
-                getbyte();
+                getbyte(jpeg);
             break;
         }
     }
     return 0;
 }
 
-static void dec_initscans(void)
+static void dec_initscans(struct jpeg_decdata *jpeg)
 {
     int i;
 
-    info.nm = info.dri + 1;
-    info.rm = M_RST0;
-    for (i = 0; i < info.ns; i++)
-        dscans[i].dc = 0;
+    jpeg->info.nm = jpeg->info.dri + 1;
+    jpeg->info.rm = M_RST0;
+    for (i = 0; i < jpeg->info.ns; i++)
+        jpeg->dscans[i].dc = 0;
 }
 
-static int dec_checkmarker(void)
+static int dec_checkmarker(struct jpeg_decdata *jpeg)
 {
     int i;
 
-    if (dec_readmarker(&in) != info.rm)
+    if (dec_readmarker(&jpeg->in) != jpeg->info.rm)
         return -1;
-    info.nm = info.dri;
-    info.rm = (info.rm + 1) & ~0x08;
-    for (i = 0; i < info.ns; i++)
-        dscans[i].dc = 0;
+    jpeg->info.nm = jpeg->info.dri;
+    jpeg->info.rm = (jpeg->info.rm + 1) & ~0x08;
+    for (i = 0; i < jpeg->info.ns; i++)
+        jpeg->dscans[i].dc = 0;
     return 0;
 }
 
-int jpeg_check_size(unsigned char *buf, int width, int height)
+struct jpeg_decdata *jpeg_alloc(void)
+{
+    struct jpeg_decdata *jpeg = malloc_tmphigh(sizeof(*jpeg));
+    return jpeg;
+}
+
+int jpeg_check_size(struct jpeg_decdata *jpeg, unsigned char *buf
+                    , int width, int height)
 {
-    datap = buf;
-    getbyte();
-    getbyte();
-    readtables(M_SOF0);
-    getword();
-    getbyte();
-    if (height != getword() || width != getword())
+    jpeg->datap = buf;
+    getbyte(jpeg);
+    getbyte(jpeg);
+    readtables(jpeg, M_SOF0);
+    getword(jpeg);
+    getbyte(jpeg);
+    if (height != getword(jpeg) || width != getword(jpeg))
         return 0;
     return 1;
 }
 
 int jpeg_decode(unsigned char *buf, unsigned char *pic,
                 int width, int height, int depth,
-                struct jpeg_decdata *decdata)
+                struct jpeg_decdata *jpeg)
 {
     int i, j, m, tac, tdc;
     int mcusx, mcusy, mx, my;
     int max[6];
 
-    if (!decdata || !buf || !pic)
+    if (!jpeg || !buf || !pic)
         return -1;
-    datap = buf;
-    if (getbyte() != 0xff)
+    jpeg->datap = buf;
+    if (getbyte(jpeg) != 0xff)
         return ERR_NO_SOI;
-    if (getbyte() != M_SOI)
+    if (getbyte(jpeg) != M_SOI)
         return ERR_NO_SOI;
-    if (readtables(M_SOF0))
+    if (readtables(jpeg, M_SOF0))
         return ERR_BAD_TABLES;
-    getword();
-    i = getbyte();
+    getword(jpeg);
+    i = getbyte(jpeg);
     if (i != 8)
         return ERR_NOT_8BIT;
-    if (((getword() + 15) & ~15) != height)
+    if (((getword(jpeg) + 15) & ~15) != height)
         return ERR_HEIGHT_MISMATCH;
-    if (((getword() + 15) & ~15) != width)
+    if (((getword(jpeg) + 15) & ~15) != width)
         return ERR_WIDTH_MISMATCH;
     if ((height & 15) || (width & 15))
         return ERR_BAD_WIDTH_OR_HEIGHT;
-    info.nc = getbyte();
-    if (info.nc > MAXCOMP)
+    jpeg->info.nc = getbyte(jpeg);
+    if (jpeg->info.nc > MAXCOMP)
         return ERR_TOO_MANY_COMPPS;
-    for (i = 0; i < info.nc; i++) {
+    for (i = 0; i < jpeg->info.nc; i++) {
         int h, v;
-        comps[i].cid = getbyte();
-        comps[i].hv = getbyte();
-        v = comps[i].hv & 15;
-        h = comps[i].hv >> 4;
-        comps[i].tq = getbyte();
+        jpeg->comps[i].cid = getbyte(jpeg);
+        jpeg->comps[i].hv = getbyte(jpeg);
+        v = jpeg->comps[i].hv & 15;
+        h = jpeg->comps[i].hv >> 4;
+        jpeg->comps[i].tq = getbyte(jpeg);
         if (h > 3 || v > 3)
             return ERR_ILLEGAL_HV;
-        if (comps[i].tq > 3)
+        if (jpeg->comps[i].tq > 3)
             return ERR_QUANT_TABLE_SELECTOR;
     }
-    if (readtables(M_SOS))
+    if (readtables(jpeg, M_SOS))
         return ERR_BAD_TABLES;
-    getword();
-    info.ns = getbyte();
-    if (info.ns != 3)
+    getword(jpeg);
+    jpeg->info.ns = getbyte(jpeg);
+    if (jpeg->info.ns != 3)
         return ERR_NOT_YCBCR_221111;
     for (i = 0; i < 3; i++) {
-        dscans[i].cid = getbyte();
-        tdc = getbyte();
+        jpeg->dscans[i].cid = getbyte(jpeg);
+        tdc = getbyte(jpeg);
         tac = tdc & 15;
         tdc >>= 4;
         if (tdc > 1 || tac > 1)
             return ERR_QUANT_TABLE_SELECTOR;
-        for (j = 0; j < info.nc; j++)
-            if (comps[j].cid == dscans[i].cid)
+        for (j = 0; j < jpeg->info.nc; j++)
+            if (jpeg->comps[j].cid == jpeg->dscans[i].cid)
                 break;
-        if (j == info.nc)
+        if (j == jpeg->info.nc)
             return ERR_UNKNOWN_CID_IN_SCAN;
-        dscans[i].hv = comps[j].hv;
-        dscans[i].tq = comps[j].tq;
-        dscans[i].hudc.dhuff = dec_huffdc + tdc;
-        dscans[i].huac.dhuff = dec_huffac + tac;
+        jpeg->dscans[i].hv = jpeg->comps[j].hv;
+        jpeg->dscans[i].tq = jpeg->comps[j].tq;
+        jpeg->dscans[i].hudc.dhuff = &jpeg->dhuff[tdc];
+        jpeg->dscans[i].huac.dhuff = &jpeg->dhuff[2 + tac];
     }
 
-    i = getbyte();
-    j = getbyte();
-    m = getbyte();
+    i = getbyte(jpeg);
+    j = getbyte(jpeg);
+    m = getbyte(jpeg);
 
     if (i != 0 || j != 63 || m != 0)
         return ERR_NOT_SEQUENTIAL_DCT;
 
-    if (dscans[0].cid != 1 || dscans[1].cid != 2 || dscans[2].cid != 3)
+    if (jpeg->dscans[0].cid != 1 || jpeg->dscans[1].cid != 2
+        || jpeg->dscans[2].cid != 3)
         return ERR_NOT_YCBCR_221111;
 
-    if (dscans[0].hv != 0x22 || dscans[1].hv != 0x11
-        || dscans[2].hv != 0x11)
+    if (jpeg->dscans[0].hv != 0x22 || jpeg->dscans[1].hv != 0x11
+        || jpeg->dscans[2].hv != 0x11)
         return ERR_NOT_YCBCR_221111;
 
     mcusx = width >> 4;
     mcusy = height >> 4;
 
 
-    idctqtab(quant[dscans[0].tq], decdata->dquant[0]);
-    idctqtab(quant[dscans[1].tq], decdata->dquant[1]);
-    idctqtab(quant[dscans[2].tq], decdata->dquant[2]);
-    initcol(decdata->dquant);
-    setinput(&in, datap);
+    idctqtab(jpeg->quant[jpeg->dscans[0].tq], jpeg->dquant[0]);
+    idctqtab(jpeg->quant[jpeg->dscans[1].tq], jpeg->dquant[1]);
+    idctqtab(jpeg->quant[jpeg->dscans[2].tq], jpeg->dquant[2]);
+    initcol(jpeg->dquant);
+    setinput(&jpeg->in, jpeg->datap);
 
 #if 0
     /* landing zone */
@@ -382,44 +404,44 @@ int jpeg_decode(unsigned char *buf, unsigned char *pic,
     img[len + 2] = M_EOF;
 #endif
 
-    dec_initscans();
+    dec_initscans(jpeg);
 
-    dscans[0].next = 6 - 4;
-    dscans[1].next = 6 - 4 - 1;
-    dscans[2].next = 6 - 4 - 1 - 1;        /* 411 encoding */
+    jpeg->dscans[0].next = 6 - 4;
+    jpeg->dscans[1].next = 6 - 4 - 1;
+    jpeg->dscans[2].next = 6 - 4 - 1 - 1;        /* 411 encoding */
     for (my = 0; my < mcusy; my++) {
         for (mx = 0; mx < mcusx; mx++) {
-            if (info.dri && !--info.nm)
-                if (dec_checkmarker())
+            if (jpeg->info.dri && !--jpeg->info.nm)
+                if (dec_checkmarker(jpeg))
                     return ERR_WRONG_MARKER;
 
-            decode_mcus(&in, decdata->dcts, 6, dscans, max);
-            idct(decdata->dcts, decdata->out, decdata->dquant[0],
+            decode_mcus(&jpeg->in, jpeg->dcts, 6, jpeg->dscans, max);
+            idct(jpeg->dcts, jpeg->out, jpeg->dquant[0],
                  IFIX(128.5), max[0]);
-            idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0],
+            idct(jpeg->dcts + 64, jpeg->out + 64, jpeg->dquant[0],
                  IFIX(128.5), max[1]);
-            idct(decdata->dcts + 128, decdata->out + 128,
-                 decdata->dquant[0], IFIX(128.5), max[2]);
-            idct(decdata->dcts + 192, decdata->out + 192,
-                 decdata->dquant[0], IFIX(128.5), max[3]);
-            idct(decdata->dcts + 256, decdata->out + 256,
-                 decdata->dquant[1], IFIX(0.5), max[4]);
-            idct(decdata->dcts + 320, decdata->out + 320,
-                 decdata->dquant[2], IFIX(0.5), max[5]);
+            idct(jpeg->dcts + 128, jpeg->out + 128,
+                 jpeg->dquant[0], IFIX(128.5), max[2]);
+            idct(jpeg->dcts + 192, jpeg->out + 192,
+                 jpeg->dquant[0], IFIX(128.5), max[3]);
+            idct(jpeg->dcts + 256, jpeg->out + 256,
+                 jpeg->dquant[1], IFIX(0.5), max[4]);
+            idct(jpeg->dcts + 320, jpeg->out + 320,
+                 jpeg->dquant[2], IFIX(0.5), max[5]);
 
             switch (depth) {
             case 32:
-                col221111_32(decdata->out,
+                col221111_32(jpeg->out,
                              pic + (my * 16 * mcusx + mx) * 16 * 4,
                              mcusx * 16 * 4);
                 break;
             case 24:
-                col221111(decdata->out,
+                col221111(jpeg->out,
                           pic + (my * 16 * mcusx + mx) * 16 * 3,
                           mcusx * 16 * 3);
                 break;
             case 16:
-                col221111_16(decdata->out,
+                col221111_16(jpeg->out,
                              pic + (my * 16 * mcusx + mx) * (16 * 2),
                              mcusx * (16 * 2));
                 break;
@@ -430,7 +452,7 @@ int jpeg_decode(unsigned char *buf, unsigned char *pic,
         }
     }
 
-    m = dec_readmarker(&in);
+    m = dec_readmarker(&jpeg->in);
     if (m != M_EOI)
         return ERR_NO_EOI;
 
@@ -442,8 +464,7 @@ int jpeg_decode(unsigned char *buf, unsigned char *pic,
 /****************************************************************/
 
 static int fillbits __P((struct in *, int, unsigned int));
-static int dec_rec2
-__P((struct in *, struct dec_hufftbl *, int *, int, int));
+static int dec_rec2 __P((struct in *, struct dec_hufftbl *, int *, int, int));
 
 static void setinput(struct in *in, unsigned char *p)
 {
@@ -696,7 +717,7 @@ static unsigned char zig2[64] = {
      6, 13, 17, 24, 32, 38, 47, 49
 };
 
-void idct(int *in, int *out, PREC * quant, PREC off, int max)
+static void idct(int *in, int *out, PREC * quant, PREC off, int max)
 {
     PREC t0, t1, t2, t3, t4, t5, t6, t7, t;
     PREC tmp[64], *tmpp;
diff --git a/src/jpeg.h b/src/jpeg.h
index d55f1a7..44c83d7 100644
--- a/src/jpeg.h
+++ b/src/jpeg.h
@@ -1,36 +1,10 @@
-/*
- * a tiny jpeg decoder.
- *
- * written in August 2001 by Michael Schroeder <mls at suse.de>
- */
-
 #ifndef __JPEG_H
 #define __JPEG_H
 
-#define ERR_NO_SOI 1
-#define ERR_NOT_8BIT 2
-#define ERR_HEIGHT_MISMATCH 3
-#define ERR_WIDTH_MISMATCH 4
-#define ERR_BAD_WIDTH_OR_HEIGHT 5
-#define ERR_TOO_MANY_COMPPS 6
-#define ERR_ILLEGAL_HV 7
-#define ERR_QUANT_TABLE_SELECTOR 8
-#define ERR_NOT_YCBCR_221111 9
-#define ERR_UNKNOWN_CID_IN_SCAN 10
-#define ERR_NOT_SEQUENTIAL_DCT 11
-#define ERR_WRONG_MARKER 12
-#define ERR_NO_EOI 13
-#define ERR_BAD_TABLES 14
-#define ERR_DEPTH_MISMATCH 15
-
-struct jpeg_decdata {
-    int dcts[6 * 64 + 16];
-    int out[64 * 6];
-    int dquant[3][64];
-};
-
-extern int jpeg_decode(unsigned char *, unsigned char *, int, int, int,
-		       struct jpeg_decdata *);
-extern int jpeg_check_size(unsigned char *, int, int);
+struct jpeg_decdata;
+struct jpeg_decdata *jpeg_alloc(void);
+int jpeg_decode(unsigned char *, unsigned char *, int, int, int,
+                struct jpeg_decdata *);
+int jpeg_check_size(struct jpeg_decdata *, unsigned char *, int, int);
 
 #endif
-- 
1.7.2




More information about the SeaBIOS mailing list