// Copyright (C) 1999-2017 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "truecolor16.h" #include "util.h" TrueColor16::TrueColor16(Visual* visual) { #if !(_WIN32) rx_ = visual->red_mask; gx_ = visual->green_mask; bx_ = visual->blue_mask; #endif #if _WIN32 // windows masks are plain wrong rx_ = 0x7C00; gx_ = 0x03E0; bx_ = 0x001F; #endif rm_ = decodeMask((unsigned short)rx_, &rs_); gm_ = decodeMask((unsigned short)gx_, &gs_); bm_ = decodeMask((unsigned short)bx_, &bs_); } unsigned short TrueColor16::decodeMask(unsigned short mask, int* s) { // first calc ffs for mask unsigned short m1 = mask; int m1s; for (m1s=0; m1s<16; m1s++) { if (m1 & 0x1) break; m1 >>= 1; } // then shift mask to mask a char for (int i=0; i<16; i++) { if (mask & 0x8000) break; mask <<= 1; } mask >>= 8; // now calc ffs for new mask unsigned short m2 = mask; int m2s; for (m2s=0; m2s<16; m2s++) { if (m2 & 0x1) break; m2 >>= 1; } *s = m1s-m2s; return mask; } void TrueColor16::encodeTrueColor(XColor* src, char* dest, XImage* ximage) { if (!ximage) return; int msb = ximage->byte_order; unsigned short r = (unsigned char)src->red; unsigned short g = (unsigned char)src->green; unsigned short b = (unsigned char)src->blue; unsigned short v = 0; v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 2); else { unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+1); *(dest+1) = *(rr); } } void TrueColor16::decodeTrueColor(char* src, XColor* dest, XImage* ximage) { if (!ximage) return; int msb = ximage->byte_order; unsigned short v = 0; if ((!msb && lsb()) || (msb && !lsb())) memcpy(dest, &v, 2); else { unsigned char* rr = (unsigned char*)(&v); *(rr+1) = *(src+0); *(rr+0) = *(src+1); } dest->red = (unsigned short)((v & rx_) >> rs_); dest->green = (unsigned short)((v & gx_) >> gs_); dest->blue = (unsigned short)((v & bx_) >> bs_); } void TrueColor16::encodeTrueColor(unsigned char* src, XImage* ximage) { int& width = ximage->width; int& height = ximage->height; char* data = ximage->data; int msb = ximage->byte_order; const unsigned char* ptr = src; if ((!msb && lsb()) || (msb && !lsb())) { for (int jj=0; jjbytes_per_line; // may be padded at the end for (int ii=0; ii0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); memcpy(dest, &v, 2); } } } else { for (int jj=0; jjbytes_per_line; for (int ii=0; ii0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); unsigned char* rr = (unsigned char*)(&v); *(dest) = *(rr+1); *(dest+1) = *(rr); } } } }