File:  [Qemu by Fabrice Bellard] / qemu / pflib.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:33:59 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1000, qemu0151, qemu0150, qemu0141, qemu0140, HEAD
qemu 0.14.0

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

unix.superglobalmegacorp.com