Annotation of qemu/pflib.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * PixelFormat conversion library.
                      3:  *
                      4:  * Author: Gerd Hoffmann <kraxel@redhat.com>
                      5:  *
                      6:  * This work is licensed under the terms of the GNU GPL, version 2.  See
                      7:  * the COPYING file in the top-level directory.
                      8:  *
1.1.1.3 ! root        9:  * Contributions after 2012-01-13 are licensed under the terms of the
        !            10:  * GNU GPL, version 2 or (at your option) any later version.
1.1       root       11:  */
                     12: #include "qemu-common.h"
                     13: #include "console.h"
                     14: #include "pflib.h"
                     15: 
                     16: typedef struct QemuPixel QemuPixel;
                     17: 
                     18: typedef void (*pf_convert)(QemuPfConv *conv,
                     19:                            void *dst, void *src, uint32_t cnt);
                     20: typedef void (*pf_convert_from)(PixelFormat *pf,
                     21:                                 QemuPixel *dst, void *src, uint32_t cnt);
                     22: typedef void (*pf_convert_to)(PixelFormat *pf,
                     23:                               void *dst, QemuPixel *src, uint32_t cnt);
                     24: 
                     25: struct QemuPfConv {
                     26:     pf_convert        convert;
                     27:     PixelFormat       src;
                     28:     PixelFormat       dst;
                     29: 
                     30:     /* for copy_generic() */
                     31:     pf_convert_from   conv_from;
                     32:     pf_convert_to     conv_to;
                     33:     QemuPixel         *conv_buf;
                     34:     uint32_t          conv_cnt;
                     35: };
                     36: 
                     37: struct QemuPixel {
                     38:     uint8_t red;
                     39:     uint8_t green;
                     40:     uint8_t blue;
                     41:     uint8_t alpha;
                     42: };
                     43: 
                     44: /* ----------------------------------------------------------------------- */
                     45: /* PixelFormat -> QemuPixel conversions                                    */
                     46: 
                     47: static void conv_16_to_pixel(PixelFormat *pf,
                     48:                              QemuPixel *dst, void *src, uint32_t cnt)
                     49: {
                     50:     uint16_t *src16 = src;
                     51: 
                     52:     while (cnt > 0) {
                     53:         dst->red   = ((*src16 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
                     54:         dst->green = ((*src16 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
                     55:         dst->blue  = ((*src16 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
                     56:         dst->alpha = ((*src16 & pf->amask) >> pf->ashift) << (8 - pf->abits);
                     57:         dst++, src16++, cnt--;
                     58:     }
                     59: }
                     60: 
                     61: /* assumes pf->{r,g,b,a}bits == 8 */
                     62: static void conv_32_to_pixel_fast(PixelFormat *pf,
                     63:                                   QemuPixel *dst, void *src, uint32_t cnt)
                     64: {
                     65:     uint32_t *src32 = src;
                     66: 
                     67:     while (cnt > 0) {
                     68:         dst->red   = (*src32 & pf->rmask) >> pf->rshift;
                     69:         dst->green = (*src32 & pf->gmask) >> pf->gshift;
                     70:         dst->blue  = (*src32 & pf->bmask) >> pf->bshift;
                     71:         dst->alpha = (*src32 & pf->amask) >> pf->ashift;
                     72:         dst++, src32++, cnt--;
                     73:     }
                     74: }
                     75: 
                     76: static void conv_32_to_pixel_generic(PixelFormat *pf,
                     77:                                      QemuPixel *dst, void *src, uint32_t cnt)
                     78: {
                     79:     uint32_t *src32 = src;
                     80: 
                     81:     while (cnt > 0) {
                     82:         if (pf->rbits < 8) {
                     83:             dst->red   = ((*src32 & pf->rmask) >> pf->rshift) << (8 - pf->rbits);
                     84:         } else {
                     85:             dst->red   = ((*src32 & pf->rmask) >> pf->rshift) >> (pf->rbits - 8);
                     86:         }
                     87:         if (pf->gbits < 8) {
                     88:             dst->green = ((*src32 & pf->gmask) >> pf->gshift) << (8 - pf->gbits);
                     89:         } else {
                     90:             dst->green = ((*src32 & pf->gmask) >> pf->gshift) >> (pf->gbits - 8);
                     91:         }
                     92:         if (pf->bbits < 8) {
                     93:             dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) << (8 - pf->bbits);
                     94:         } else {
                     95:             dst->blue  = ((*src32 & pf->bmask) >> pf->bshift) >> (pf->bbits - 8);
                     96:         }
                     97:         if (pf->abits < 8) {
                     98:             dst->alpha = ((*src32 & pf->amask) >> pf->ashift) << (8 - pf->abits);
                     99:         } else {
                    100:             dst->alpha = ((*src32 & pf->amask) >> pf->ashift) >> (pf->abits - 8);
                    101:         }
                    102:         dst++, src32++, cnt--;
                    103:     }
                    104: }
                    105: 
                    106: /* ----------------------------------------------------------------------- */
                    107: /* QemuPixel -> PixelFormat conversions                                    */
                    108: 
                    109: static void conv_pixel_to_16(PixelFormat *pf,
                    110:                              void *dst, QemuPixel *src, uint32_t cnt)
                    111: {
                    112:     uint16_t *dst16 = dst;
                    113: 
                    114:     while (cnt > 0) {
                    115:         *dst16  = ((uint16_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
                    116:         *dst16 |= ((uint16_t)src->green >> (8 - pf->gbits)) << pf->gshift;
                    117:         *dst16 |= ((uint16_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
                    118:         *dst16 |= ((uint16_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
                    119:         dst16++, src++, cnt--;
                    120:     }
                    121: }
                    122: 
                    123: static void conv_pixel_to_32(PixelFormat *pf,
                    124:                              void *dst, QemuPixel *src, uint32_t cnt)
                    125: {
                    126:     uint32_t *dst32 = dst;
                    127: 
                    128:     while (cnt > 0) {
                    129:         *dst32  = ((uint32_t)src->red   >> (8 - pf->rbits)) << pf->rshift;
                    130:         *dst32 |= ((uint32_t)src->green >> (8 - pf->gbits)) << pf->gshift;
                    131:         *dst32 |= ((uint32_t)src->blue  >> (8 - pf->bbits)) << pf->bshift;
                    132:         *dst32 |= ((uint32_t)src->alpha >> (8 - pf->abits)) << pf->ashift;
                    133:         dst32++, src++, cnt--;
                    134:     }
                    135: }
                    136: 
                    137: /* ----------------------------------------------------------------------- */
                    138: /* PixelFormat -> PixelFormat conversions                                  */
                    139: 
                    140: static void convert_copy(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
                    141: {
                    142:     uint32_t bytes = cnt * conv->src.bytes_per_pixel;
                    143:     memcpy(dst, src, bytes);
                    144: }
                    145: 
                    146: static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
                    147: {
                    148:     if (conv->conv_cnt < cnt) {
                    149:         conv->conv_cnt = cnt;
1.1.1.2   root      150:         conv->conv_buf = g_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
1.1       root      151:     }
                    152:     conv->conv_from(&conv->src, conv->conv_buf, src, cnt);
                    153:     conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt);
                    154: }
                    155: 
                    156: /* ----------------------------------------------------------------------- */
                    157: /* public interface                                                        */
                    158: 
                    159: QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
                    160: {
1.1.1.2   root      161:     QemuPfConv *conv = g_malloc0(sizeof(QemuPfConv));
1.1       root      162: 
                    163:     conv->src = *src;
                    164:     conv->dst = *dst;
                    165: 
                    166:     if (memcmp(&conv->src, &conv->dst, sizeof(PixelFormat)) == 0) {
                    167:         /* formats identical, can simply copy */
                    168:         conv->convert = convert_copy;
                    169:     } else {
                    170:         /* generic two-step conversion: src -> QemuPixel -> dst  */
                    171:         switch (conv->src.bytes_per_pixel) {
                    172:         case 2:
                    173:             conv->conv_from = conv_16_to_pixel;
                    174:             break;
                    175:         case 4:
                    176:             if (conv->src.rbits == 8 && conv->src.gbits == 8 && conv->src.bbits == 8) {
                    177:                 conv->conv_from = conv_32_to_pixel_fast;
                    178:             } else {
                    179:                 conv->conv_from = conv_32_to_pixel_generic;
                    180:             }
                    181:             break;
                    182:         default:
                    183:             goto err;
                    184:         }
                    185:         switch (conv->dst.bytes_per_pixel) {
                    186:         case 2:
                    187:             conv->conv_to = conv_pixel_to_16;
                    188:             break;
                    189:         case 4:
                    190:             conv->conv_to = conv_pixel_to_32;
                    191:             break;
                    192:         default:
                    193:             goto err;
                    194:         }
                    195:         conv->convert = convert_generic;
                    196:     }
                    197:     return conv;
                    198: 
                    199: err:
1.1.1.2   root      200:     g_free(conv);
1.1       root      201:     return NULL;
                    202: }
                    203: 
                    204: void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
                    205: {
                    206:     conv->convert(conv, dst, src, cnt);
                    207: }
                    208: 
                    209: void qemu_pf_conv_put(QemuPfConv *conv)
                    210: {
                    211:     if (conv) {
1.1.1.2   root      212:         g_free(conv->conv_buf);
                    213:         g_free(conv);
1.1       root      214:     }
                    215: }

unix.superglobalmegacorp.com