Changeset c6f08726 in mainline for uspace/lib/imgmap/imgmap.c


Ignore:
Timestamp:
2011-08-11T14:14:53Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8d8eeb9
Parents:
67b05ff
Message:

eradicate PPMs and pixmaps completely
make TGA and image map code more robust

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/imgmap/imgmap.c

    r67b05ff rc6f08726  
    6969        IMG_CMAP = 1,
    7070        IMG_BGRA = 2,
    71         IMG_BW = 3,
     71        IMG_GRAY = 3,
    7272        IMG_CMAP_RLE = 9,
    7373        IMG_BGRA_RLE = 10,
    74         IMG_BW_RLE = 11
     74        IMG_GRAY_RLE = 11
    7575} img_type_t;
    7676
     
    104104 *
    105105 * @param[in]  data Memory representation of TGA.
     106 * @param[in]  size Size of the representation (in bytes).
    106107 * @param[out] tga  Decoded TGA.
    107108 *
     
    110111 *
    111112 */
    112 static bool decode_tga_header(void *data, tga_t *tga)
     113static bool decode_tga_header(void *data, size_t size, tga_t *tga)
    113114{
     115        /* Header sanity check */
     116        if (size < sizeof(tga_header_t))
     117                return false;
     118       
    114119        tga_header_t *head = (tga_header_t *) data;
    115120       
     
    117122        tga->id_data = data + sizeof(tga_header_t);
    118123        tga->id_length = head->id_length;
     124       
     125        if (size < sizeof(tga_header_t) + tga->id_length)
     126                return false;
    119127       
    120128        /* Color map type */
     
    130138        tga->cmap_data = tga->id_data + tga->id_length;
    131139        tga->cmap_length = ALIGN_UP(tga->cmap_entries * tga->cmap_bpp, 8) >> 3;
     140       
     141        if (size < sizeof(tga_header_t) + tga->id_length +
     142            tga->cmap_length)
     143                return false;
    132144       
    133145        /* Image specification */
     
    142154        tga->img_length = ALIGN_UP(tga->width * tga->height * tga->img_bpp, 8) >> 3;
    143155       
     156        if (size < sizeof(tga_header_t) + tga->id_length +
     157            tga->cmap_length + tga->img_length)
     158                return false;
     159       
    144160        return true;
    145161}
     
    152168 * alpha channel.
    153169 *
    154  * @param data[in] Memory representation of TGA.
     170 * @param[in] data Memory representation of TGA.
     171 * @param[in] size Size of the representation (in bytes).
    155172 *
    156173 * @return Newly allocated image map.
     
    158175 *
    159176 */
    160 imgmap_t *imgmap_decode_tga(void *data)
     177imgmap_t *imgmap_decode_tga(void *data, size_t size)
    161178{
    162179        tga_t tga;
    163         if (!decode_tga_header(data, &tga))
     180        if (!decode_tga_header(data, size, &tga))
    164181                return NULL;
    165182       
     
    178195        switch (tga.img_type) {
    179196        case IMG_BGRA:
     197                if (tga.img_bpp != 24)
     198                        return NULL;
     199                break;
     200        case IMG_GRAY:
     201                if (tga.img_bpp != 8)
     202                        return NULL;
    180203                break;
    181204        default:
     
    184207        }
    185208       
    186         if (tga.img_bpp != 24)
    187                 return NULL;
    188        
    189209        if (tga.img_alpha_bpp != 0)
    190210                return NULL;
     
    192212        sysarg_t twidth = tga.startx + tga.width;
    193213        sysarg_t theight = tga.starty + tga.height;
    194         size_t size = twidth * theight * 3;
    195        
    196         imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + size);
     214        size_t bsize = twidth * theight * 3;
     215       
     216        imgmap_t *imgmap = (imgmap_t *) malloc(sizeof(imgmap_t) + bsize);
    197217        if (imgmap == NULL)
    198218                return NULL;
    199219       
    200         imgmap->tag = 'I';
    201         imgmap->size = sizeof(imgmap_t) + size;
     220        imgmap->size = sizeof(imgmap_t) + bsize;
    202221        imgmap->width = twidth;
    203222        imgmap->height = theight;
    204223        imgmap->visual = VISUAL_BGR_8_8_8;
    205224       
    206         memset(imgmap->data, 0, size);
    207        
    208         for (sysarg_t y = tga.starty; y < theight; y++) {
    209                 size_t src_offset = (y - tga.starty) * tga.width * 3;
    210                 size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
    211                
    212                 memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
    213                     tga.width * 3);
     225        memset(imgmap->data, 0, bsize);
     226       
     227        /*
     228         * TGA is encoded in a bottom-up manner.
     229         */
     230       
     231        switch (tga.img_type) {
     232        case IMG_BGRA:
     233                for (sysarg_t y = tga.starty; y < theight; y++) {
     234                        size_t src_offset = (y - tga.starty) * tga.width * 3;
     235                        size_t dst_offset = ((theight - y - 1) * twidth + tga.startx) * 3;
     236                       
     237                        memcpy(imgmap->data + dst_offset, tga.img_data + src_offset,
     238                            tga.width * 3);
     239                }
     240                break;
     241        case IMG_GRAY:
     242                for (sysarg_t y = tga.starty; y < theight; y++) {
     243                        for (sysarg_t x = tga.startx; x < twidth; x++) {
     244                                uint8_t val =
     245                                    ((uint8_t *) tga.img_data)[(y - tga.starty) * tga.width + (x - tga.startx)];
     246                                size_t dst_offset = ((theight - y - 1) * twidth + x) * 3;
     247                                memset(imgmap->data + dst_offset, val, 3);
     248                        }
     249                }
     250                break;
     251        default:
     252                break;
    214253        }
    215254       
Note: See TracChangeset for help on using the changeset viewer.