00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CXWindowsClipboardAnyBitmapConverter.h"
00016
00017
00018 struct CBMPInfoHeader {
00019 public:
00020 UInt32 biSize;
00021 SInt32 biWidth;
00022 SInt32 biHeight;
00023 UInt16 biPlanes;
00024 UInt16 biBitCount;
00025 UInt32 biCompression;
00026 UInt32 biSizeImage;
00027 SInt32 biXPelsPerMeter;
00028 SInt32 biYPelsPerMeter;
00029 UInt32 biClrUsed;
00030 UInt32 biClrImportant;
00031 };
00032
00033
00034
00035 static
00036 void
00037 toLE(UInt8*& dst, UInt16 src)
00038 {
00039 dst[0] = static_cast<UInt8>(src & 0xffu);
00040 dst[1] = static_cast<UInt8>((src >> 8) & 0xffu);
00041 dst += 2;
00042 }
00043
00044 static
00045 void
00046 toLE(UInt8*& dst, SInt32 src)
00047 {
00048 dst[0] = static_cast<UInt8>(src & 0xffu);
00049 dst[1] = static_cast<UInt8>((src >> 8) & 0xffu);
00050 dst[2] = static_cast<UInt8>((src >> 16) & 0xffu);
00051 dst[3] = static_cast<UInt8>((src >> 24) & 0xffu);
00052 dst += 4;
00053 }
00054
00055 static
00056 void
00057 toLE(UInt8*& dst, UInt32 src)
00058 {
00059 dst[0] = static_cast<UInt8>(src & 0xffu);
00060 dst[1] = static_cast<UInt8>((src >> 8) & 0xffu);
00061 dst[2] = static_cast<UInt8>((src >> 16) & 0xffu);
00062 dst[3] = static_cast<UInt8>((src >> 24) & 0xffu);
00063 dst += 4;
00064 }
00065
00066 static inline
00067 UInt16
00068 fromLEU16(const UInt8* data)
00069 {
00070 return static_cast<UInt16>(data[0]) |
00071 (static_cast<UInt16>(data[1]) << 8);
00072 }
00073
00074 static inline
00075 SInt32
00076 fromLES32(const UInt8* data)
00077 {
00078 return static_cast<SInt32>(static_cast<UInt32>(data[0]) |
00079 (static_cast<UInt32>(data[1]) << 8) |
00080 (static_cast<UInt32>(data[2]) << 16) |
00081 (static_cast<UInt32>(data[3]) << 24));
00082 }
00083
00084 static inline
00085 UInt32
00086 fromLEU32(const UInt8* data)
00087 {
00088 return static_cast<UInt32>(data[0]) |
00089 (static_cast<UInt32>(data[1]) << 8) |
00090 (static_cast<UInt32>(data[2]) << 16) |
00091 (static_cast<UInt32>(data[3]) << 24);
00092 }
00093
00094
00095
00096
00097
00098
00099 CXWindowsClipboardAnyBitmapConverter::CXWindowsClipboardAnyBitmapConverter()
00100 {
00101
00102 }
00103
00104 CXWindowsClipboardAnyBitmapConverter::~CXWindowsClipboardAnyBitmapConverter()
00105 {
00106
00107 }
00108
00109 IClipboard::EFormat
00110 CXWindowsClipboardAnyBitmapConverter::getFormat() const
00111 {
00112 return IClipboard::kBitmap;
00113 }
00114
00115 int
00116 CXWindowsClipboardAnyBitmapConverter::getDataSize() const
00117 {
00118 return 8;
00119 }
00120
00121 CString
00122 CXWindowsClipboardAnyBitmapConverter::fromIClipboard(const CString& bmp) const
00123 {
00124
00125 CBMPInfoHeader infoHeader;
00126 const UInt8* rawBMPInfoHeader = reinterpret_cast<const UInt8*>(bmp.data());
00127 infoHeader.biSize = fromLEU32(rawBMPInfoHeader + 0);
00128 infoHeader.biWidth = fromLES32(rawBMPInfoHeader + 4);
00129 infoHeader.biHeight = fromLES32(rawBMPInfoHeader + 8);
00130 infoHeader.biPlanes = fromLEU16(rawBMPInfoHeader + 12);
00131 infoHeader.biBitCount = fromLEU16(rawBMPInfoHeader + 14);
00132 infoHeader.biCompression = fromLEU32(rawBMPInfoHeader + 16);
00133 infoHeader.biSizeImage = fromLEU32(rawBMPInfoHeader + 20);
00134 infoHeader.biXPelsPerMeter = fromLES32(rawBMPInfoHeader + 24);
00135 infoHeader.biYPelsPerMeter = fromLES32(rawBMPInfoHeader + 28);
00136 infoHeader.biClrUsed = fromLEU32(rawBMPInfoHeader + 32);
00137 infoHeader.biClrImportant = fromLEU32(rawBMPInfoHeader + 36);
00138
00139
00140 if (infoHeader.biSize != 40 ||
00141 infoHeader.biWidth == 0 || infoHeader.biHeight == 0 ||
00142 infoHeader.biPlanes != 0 || infoHeader.biCompression != 0 ||
00143 (infoHeader.biBitCount != 24 && infoHeader.biBitCount != 32)) {
00144 return CString();
00145 }
00146
00147
00148 const UInt8* rawBMPPixels = rawBMPInfoHeader + 40;
00149 if (infoHeader.biBitCount == 24) {
00150 return doBGRFromIClipboard(rawBMPPixels,
00151 infoHeader.biWidth, infoHeader.biHeight);
00152 }
00153 else {
00154 return doBGRAFromIClipboard(rawBMPPixels,
00155 infoHeader.biWidth, infoHeader.biHeight);
00156 }
00157 }
00158
00159 CString
00160 CXWindowsClipboardAnyBitmapConverter::toIClipboard(const CString& image) const
00161 {
00162
00163 UInt32 w, h, depth;
00164 CString rawBMP = doToIClipboard(image, w, h, depth);
00165 if (rawBMP.empty() || w == 0 || h == 0 || (depth != 24 && depth != 32)) {
00166 return CString();
00167 }
00168
00169
00170 UInt8 infoHeader[40];
00171 UInt8* dst = infoHeader;
00172 toLE(dst, static_cast<UInt32>(40));
00173 toLE(dst, static_cast<SInt32>(w));
00174 toLE(dst, static_cast<SInt32>(h));
00175 toLE(dst, static_cast<UInt16>(1));
00176 toLE(dst, static_cast<UInt16>(depth));
00177 toLE(dst, static_cast<UInt32>(0));
00178 toLE(dst, static_cast<UInt32>(image.size()));
00179 toLE(dst, static_cast<SInt32>(2834));
00180 toLE(dst, static_cast<SInt32>(2834));
00181 toLE(dst, static_cast<UInt32>(0));
00182 toLE(dst, static_cast<UInt32>(0));
00183
00184
00185 return CString(reinterpret_cast<const char*>(infoHeader),
00186 sizeof(infoHeader)) + rawBMP;
00187 }