543
570
if (x > image->width || y > image->height)
545
572
row = image->data + (y * image->stride);
546
switch (image->format) {
573
switch (effective_format(image->format, image->bpp)) {
547
574
case XCB_IMAGE_FORMAT_XY_BITMAP:
548
575
case XCB_IMAGE_FORMAT_XY_PIXMAP:
551
578
uint32_t plane_mask = image->plane_mask;
552
579
uint8_t * plane = row;
553
uint32_t ulog = image->bpp >> 4;
554
uint32_t unit = (x >> 3) & ~xcb_mask(ulog);
555
uint32_t byte = (x >> 3) & xcb_mask(ulog);
556
uint32_t bit = x & 7;
580
uint32_t byte = xy_image_byte(image, x);
581
uint32_t bit = xy_image_bit(image,x);
582
uint8_t mask = 1 << bit;
558
if (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
559
byte = xcb_mask(ulog) - byte;
560
if (image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) {
563
pixel = xcb_bit_reverse(pixel, image->bpp);
564
plane_mask = xcb_bit_reverse(plane_mask, image->bpp);
566
for (p = 0; p < image->bpp; p++) {
567
if (plane_mask & 1) {
568
uint8_t * bp = plane + (unit | byte);
569
uint8_t m = 1 << bit;
570
uint8_t p = (pixel & 1) << bit;
571
*bp = (*bp & ~m) | p;
584
for (p = image->bpp - 1; p >= 0; p--) {
585
if ((plane_mask >> p) & 1) {
586
uint8_t * bp = plane + byte;
587
uint8_t this_bit = ((pixel >> p) & 1) << bit;
588
*bp = (*bp & ~mask) | this_bit;
573
590
plane += image->stride * image->height;
658
673
assert(x < image->width && y < image->height);
659
674
row = image->data + (y * image->stride);
660
switch (image->format) {
675
switch (effective_format(image->format, image->bpp)) {
661
676
case XCB_IMAGE_FORMAT_XY_BITMAP:
662
677
case XCB_IMAGE_FORMAT_XY_PIXMAP:
665
680
uint32_t plane_mask = image->plane_mask;
666
681
uint8_t * plane = row;
667
uint32_t ulog = image->bpp >> 4;
668
uint32_t unit = (x >> 3) & ~xcb_mask(ulog);
669
uint32_t byte = (x >> 3) & xcb_mask(ulog);
670
uint32_t bit = x & 7;
682
uint32_t byte = xy_image_byte(image, x);
683
uint32_t bit = xy_image_bit(image,x);
672
if (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
673
byte = xcb_mask(ulog) - byte;
674
if (image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) {
677
plane_mask = xcb_bit_reverse(plane_mask, image->bpp);
679
for (p = 0; p < image->bpp; p++) {
685
for (p = image->bpp - 1; p >= 0; p--) {
681
if (plane_mask & 1) {
682
uint8_t * bp = plane + (unit | byte);
687
if ((plane_mask >> p) & 1) {
688
uint8_t * bp = plane + byte;
683
689
pixel |= (*bp >> bit) & 1;
685
691
plane += image->stride * image->height;
688
if (image->bit_order == XCB_IMAGE_ORDER_LSB_FIRST)
689
pixel = xcb_bit_reverse(pixel, image->bpp);
692
695
case XCB_IMAGE_FORMAT_Z_PIXMAP:
855
855
b = (b << 4) | (b >> 4);
858
if (++minor == unit_bytes)
864
858
src += src_stride;
865
859
dst += dst_stride;
869
/* Note that all of these permutations are self-inverse.
870
Applying them twice yields the identity permutation, i.e p*p = i
871
This means that we only have to care about the
872
source and destination size and whether they mismatch, not
873
the actual endiannesses. */
874
static uint8_t const forward_order[4] = {0, 1, 2, 3};
875
static uint8_t const reverse_order[4] = {3, 2, 1, 0};
876
static uint8_t const reverse_word_order[4] = {2, 3, 0, 1};
878
static uint8_t const *
879
conversion_byte_order(xcb_image_t *src, xcb_image_t *dst)
881
uint8_t nbytes = src->unit >> 3;
863
/* Which order are bytes in (low two bits), given
864
* code which accesses an image one byte at a time
867
byte_order(xcb_image_t *i)
869
uint32_t flip = i->byte_order == XCB_IMAGE_ORDER_MSB_FIRST;
878
return flip | (flip << 1);
883
bit_order(xcb_image_t *i)
885
uint32_t flip = i->byte_order != i->bit_order;
894
return flip | (flip << 1);
898
/* Convert from one byte order to another by flipping the
899
* low two bits of the byte index along a scanline
902
conversion_byte_swap(xcb_image_t *src, xcb_image_t *dst)
904
xcb_image_format_t ef = effective_format(src->format, src->bpp);
883
if (src->byte_order == dst->byte_order)
884
return forward_order;
885
if (nbytes >= 1 && nbytes <= 4)
886
return &reverse_order[4 - nbytes];
887
return forward_order;
891
#define R1 forward_order
892
#define R2 reverse_word_order
893
#define R4 reverse_order
894
#define W4 reverse_word_order
896
static uint8_t const * const bbo_reverse[3][3] =
900
/*32*/ {R4, W4, R4}};
902
static uint8_t const *
903
bitmap_conversion_byte_order(xcb_image_t *src, xcb_image_t *dst)
905
uint8_t srclog = src->unit >> 4;
906
uint8_t dstlog = dst->unit >> 4;
907
int sbo = src->byte_order;
908
int dbo = dst->byte_order;
911
sbo = XCB_IMAGE_ORDER_LSB_FIRST;
913
dbo = XCB_IMAGE_ORDER_LSB_FIRST;
915
return forward_order;
916
return bbo_reverse[srclog][dstlog];
906
/* src_ef == dst_ef in all callers of this function */
907
if (ef == XCB_IMAGE_FORMAT_XY_PIXMAP) {
908
return bit_order(src) ^ bit_order(dst);
910
/* src_bpp == dst_bpp in all callers of this function */
911
return byte_order(src) ^ byte_order(dst);
921
916
xcb_image_convert (xcb_image_t * src,
922
917
xcb_image_t * dst)
926
int format_compatible = 0;
928
919
xcb_image_format_t ef = effective_format(src->format, src->bpp);
930
921
/* Things will go horribly wrong here if a bad
932
923
up front just to be nice. */
933
924
assert(image_format_valid(src));
934
925
assert(image_format_valid(dst));
935
if (src->depth != dst->depth ||
936
src->width != dst->width ||
927
/* images must be the same size
928
* (yes, we could copy a sub-set)
930
if (src->width != dst->width ||
937
931
src->height != dst->height)
940
case XCB_IMAGE_FORMAT_XY_PIXMAP:
941
bitmap = src->depth == 1;
942
format_compatible = src->format == dst->format || bitmap;
943
/* Case: Formats are identical. Just copy. */
944
if (format_compatible &&
945
src->bpp == dst->bpp &&
946
src->unit == dst->unit &&
947
src->scanline_pad == dst->scanline_pad &&
948
src->byte_order == dst->byte_order &&
949
src->bit_order == dst->bit_order) {
950
memcpy(dst->data, src->data, src->size);
954
case XCB_IMAGE_FORMAT_Z_PIXMAP:
955
format_compatible = src->format == dst->format;
956
/* Case: Formats are identical. Just copy. */
957
if (format_compatible &&
958
src->bpp == dst->bpp &&
959
src->byte_order == dst->byte_order) {
960
memcpy(dst->data, src->data, src->size);
967
/* Case: Bitmap scanline units are always compatible. Copy and convert. */
969
uint8_t const * const
970
byte_order = bitmap_conversion_byte_order(src, dst);
971
int bitswap = src->bit_order != dst->bit_order;
972
uint8_t unit = src->unit;
974
if (dst->unit < unit)
976
swap_image(src->data, src->stride,
977
dst->data, dst->stride,
978
byte_order, unit >> 3,
979
src->height, bitswap, 0);
982
/* Case: Pixmap scanline units are identical. Copy and convert. */
983
if (format_compatible && src->bpp == dst->bpp) {
984
uint8_t const * const
985
byte_order = conversion_byte_order(src, dst);
986
int bitswap = src->bit_order != dst->bit_order;
987
int nibbleswap = src->byte_order != dst->byte_order &&
989
swap_image(src->data, src->stride,
990
dst->data, dst->stride,
991
byte_order, src->unit >> 3,
992
src->height, bitswap, nibbleswap);
996
/* General case: Slow pixel copy. Should we optimize
997
Z24<->Z32 copies of either endianness? */
998
for (y = 0; y < src->height; y++) {
999
for (x = 0; x < src->width; x++) {
1000
uint32_t pixel = xcb_image_get_pixel(src, x, y);
1001
xcb_image_put_pixel(dst, x, y, pixel);
934
if (ef == effective_format(dst->format, dst->bpp) &&
935
src->bpp == dst->bpp)
937
if (src->unit == dst->unit &&
938
src->scanline_pad == dst->scanline_pad &&
939
src->byte_order == dst->byte_order &&
940
(ef == XCB_IMAGE_FORMAT_Z_PIXMAP ||
941
src->bit_order == dst->bit_order)) {
942
memcpy(dst->data, src->data, src->size);
946
uint32_t byteswap = conversion_byte_swap(src, dst);
947
uint32_t height = src->height;;
949
if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP) {
950
if (src->bpp == 4 && src->byte_order != dst->byte_order)
953
if (src->bit_order != dst->bit_order)
955
height *= src->depth;
957
swap_image (src->data, src->stride, dst->data, dst->stride,
958
height, byteswap, bitswap, nibbleswap);
965
/* General case: Slow pixel copy. Should we optimize
966
Z24<->Z32 copies of either endianness? */
967
for (y = 0; y < src->height; y++) {
968
for (x = 0; x < src->width; x++) {
969
uint32_t pixel = xcb_image_get_pixel(src, x, y);
970
xcb_image_put_pixel(dst, x, y, pixel);