/indra/llimage/llimagebmp.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 653 lines · 493 code · 90 blank · 70 comment · 86 complexity · 9c7a0e1a7b487430eccca1aba58e1f2a MD5 · raw file

  1. /**
  2. * @file llimagebmp.cpp
  3. *
  4. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  5. * Second Life Viewer Source Code
  6. * Copyright (C) 2010, Linden Research, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation;
  11. * version 2.1 of the License only.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  23. * $/LicenseInfo$
  24. */
  25. #include "linden_common.h"
  26. #include "llimagebmp.h"
  27. #include "llerror.h"
  28. #include "llendianswizzle.h"
  29. /**
  30. * @struct LLBMPHeader
  31. *
  32. * This struct helps deal with bmp files.
  33. */
  34. struct LLBMPHeader
  35. {
  36. S32 mSize;
  37. S32 mWidth;
  38. S32 mHeight;
  39. S16 mPlanes;
  40. S16 mBitsPerPixel;
  41. S16 mCompression;
  42. S16 mAlignmentPadding; // pads out to next word boundary
  43. S32 mImageSize;
  44. S32 mHorzPelsPerMeter;
  45. S32 mVertPelsPerMeter;
  46. S32 mNumColors;
  47. S32 mNumColorsImportant;
  48. };
  49. /**
  50. * @struct Win95BmpHeaderExtension
  51. */
  52. struct Win95BmpHeaderExtension
  53. {
  54. U32 mReadMask;
  55. U32 mGreenMask;
  56. U32 mBlueMask;
  57. U32 mAlphaMask;
  58. U32 mColorSpaceType;
  59. U16 mRed[3]; // Red CIE endpoint
  60. U16 mGreen[3]; // Green CIE endpoint
  61. U16 mBlue[3]; // Blue CIE endpoint
  62. U32 mGamma[3]; // Gamma scale for r g and b
  63. };
  64. /**
  65. * LLImageBMP
  66. */
  67. LLImageBMP::LLImageBMP()
  68. :
  69. LLImageFormatted(IMG_CODEC_BMP),
  70. mColorPaletteColors( 0 ),
  71. mColorPalette( NULL ),
  72. mBitmapOffset( 0 ),
  73. mBitsPerPixel( 0 ),
  74. mOriginAtTop( FALSE )
  75. {
  76. mBitfieldMask[0] = 0;
  77. mBitfieldMask[1] = 0;
  78. mBitfieldMask[2] = 0;
  79. mBitfieldMask[3] = 0;
  80. }
  81. LLImageBMP::~LLImageBMP()
  82. {
  83. delete[] mColorPalette;
  84. }
  85. BOOL LLImageBMP::updateData()
  86. {
  87. resetLastError();
  88. // Check to make sure that this instance has been initialized with data
  89. U8* mdata = getData();
  90. if (!mdata || (0 == getDataSize()))
  91. {
  92. setLastError("Uninitialized instance of LLImageBMP");
  93. return FALSE;
  94. }
  95. // Read the bitmap headers in order to get all the useful info
  96. // about this image
  97. ////////////////////////////////////////////////////////////////////
  98. // Part 1: "File Header"
  99. // 14 bytes consisting of
  100. // 2 bytes: either BM or BA
  101. // 4 bytes: file size in bytes
  102. // 4 bytes: reserved (always 0)
  103. // 4 bytes: bitmap offset (starting position of image data in bytes)
  104. const S32 FILE_HEADER_SIZE = 14;
  105. if ((mdata[0] != 'B') || (mdata[1] != 'M'))
  106. {
  107. if ((mdata[0] != 'B') || (mdata[1] != 'A'))
  108. {
  109. setLastError("OS/2 bitmap array BMP files are not supported");
  110. return FALSE;
  111. }
  112. else
  113. {
  114. setLastError("Does not appear to be a bitmap file");
  115. return FALSE;
  116. }
  117. }
  118. mBitmapOffset = mdata[13];
  119. mBitmapOffset <<= 8; mBitmapOffset += mdata[12];
  120. mBitmapOffset <<= 8; mBitmapOffset += mdata[11];
  121. mBitmapOffset <<= 8; mBitmapOffset += mdata[10];
  122. ////////////////////////////////////////////////////////////////////
  123. // Part 2: "Bitmap Header"
  124. const S32 BITMAP_HEADER_SIZE = 40;
  125. LLBMPHeader header;
  126. llassert( sizeof( header ) == BITMAP_HEADER_SIZE );
  127. memcpy( /* Flawfinder: ignore */
  128. (void*)&header,
  129. mdata + FILE_HEADER_SIZE,
  130. BITMAP_HEADER_SIZE);
  131. // convert BMP header from little endian (no-op on little endian builds)
  132. llendianswizzleone(header.mSize);
  133. llendianswizzleone(header.mWidth);
  134. llendianswizzleone(header.mHeight);
  135. llendianswizzleone(header.mPlanes);
  136. llendianswizzleone(header.mBitsPerPixel);
  137. llendianswizzleone(header.mCompression);
  138. llendianswizzleone(header.mAlignmentPadding);
  139. llendianswizzleone(header.mImageSize);
  140. llendianswizzleone(header.mHorzPelsPerMeter);
  141. llendianswizzleone(header.mVertPelsPerMeter);
  142. llendianswizzleone(header.mNumColors);
  143. llendianswizzleone(header.mNumColorsImportant);
  144. BOOL windows_nt_version = FALSE;
  145. BOOL windows_95_version = FALSE;
  146. if( 12 == header.mSize )
  147. {
  148. setLastError("Windows 2.x and OS/2 1.x BMP files are not supported");
  149. return FALSE;
  150. }
  151. else
  152. if( 40 == header.mSize )
  153. {
  154. if( 3 == header.mCompression )
  155. {
  156. // Windows NT
  157. windows_nt_version = TRUE;
  158. }
  159. else
  160. {
  161. // Windows 3.x
  162. }
  163. }
  164. else
  165. if( 12 <= header.mSize && 64 <= header.mSize )
  166. {
  167. setLastError("OS/2 2.x BMP files are not supported");
  168. return FALSE;
  169. }
  170. else
  171. if( 108 == header.mSize )
  172. {
  173. // BITMAPV4HEADER
  174. windows_95_version = TRUE;
  175. }
  176. else
  177. if( 108 < header.mSize )
  178. {
  179. // BITMAPV5HEADER or greater
  180. // Should work as long at Microsoft maintained backwards compatibility (which they did in V4 and V5)
  181. windows_95_version = TRUE;
  182. }
  183. S32 width = header.mWidth;
  184. S32 height = header.mHeight;
  185. if (height < 0)
  186. {
  187. mOriginAtTop = TRUE;
  188. height = -height;
  189. }
  190. else
  191. {
  192. mOriginAtTop = FALSE;
  193. }
  194. mBitsPerPixel = header.mBitsPerPixel;
  195. S32 components;
  196. switch( mBitsPerPixel )
  197. {
  198. case 8:
  199. components = 1;
  200. break;
  201. case 24:
  202. case 32:
  203. components = 3;
  204. break;
  205. case 1:
  206. case 4:
  207. case 16: // Started work on 16, but doesn't work yet
  208. // These are legal, but we don't support them yet.
  209. setLastError("Unsupported bit depth");
  210. return FALSE;
  211. default:
  212. setLastError("Unrecognized bit depth");
  213. return FALSE;
  214. }
  215. setSize(width, height, components);
  216. switch( header.mCompression )
  217. {
  218. case 0:
  219. // Uncompressed
  220. break;
  221. case 1:
  222. setLastError("8 bit RLE compression not supported.");
  223. return FALSE;
  224. case 2:
  225. setLastError("4 bit RLE compression not supported.");
  226. return FALSE;
  227. case 3:
  228. // Windows NT or Windows 95
  229. break;
  230. default:
  231. setLastError("Unsupported compression format.");
  232. return FALSE;
  233. }
  234. ////////////////////////////////////////////////////////////////////
  235. // Part 3: Bitfield Masks and other color data
  236. S32 extension_size = 0;
  237. if( windows_nt_version )
  238. {
  239. if( (16 != header.mBitsPerPixel) && (32 != header.mBitsPerPixel) )
  240. {
  241. setLastError("Bitfield encoding requires 16 or 32 bits per pixel.");
  242. return FALSE;
  243. }
  244. if( 0 != header.mNumColors )
  245. {
  246. setLastError("Bitfield encoding is not compatible with a color table.");
  247. return FALSE;
  248. }
  249. extension_size = 4 * 3;
  250. memcpy( mBitfieldMask, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, extension_size); /* Flawfinder: ignore */
  251. }
  252. else
  253. if( windows_95_version )
  254. {
  255. Win95BmpHeaderExtension win_95_extension;
  256. extension_size = sizeof( win_95_extension );
  257. llassert( sizeof( win_95_extension ) + BITMAP_HEADER_SIZE == 108 );
  258. memcpy( &win_95_extension, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, sizeof( win_95_extension ) ); /* Flawfinder: ignore */
  259. if( 3 == header.mCompression )
  260. {
  261. memcpy( mBitfieldMask, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE, 4 * 4); /* Flawfinder: ignore */
  262. }
  263. // Color correction ignored for now
  264. }
  265. ////////////////////////////////////////////////////////////////////
  266. // Part 4: Color Palette (optional)
  267. // Note: There's no color palette if there are 16 or more bits per pixel
  268. S32 color_palette_size = 0;
  269. mColorPaletteColors = 0;
  270. if( header.mBitsPerPixel < 16 )
  271. {
  272. if( 0 == header.mNumColors )
  273. {
  274. mColorPaletteColors = (1 << header.mBitsPerPixel);
  275. }
  276. else
  277. {
  278. mColorPaletteColors = header.mNumColors;
  279. }
  280. }
  281. color_palette_size = mColorPaletteColors * 4;
  282. if( 0 != mColorPaletteColors )
  283. {
  284. mColorPalette = new U8[color_palette_size];
  285. if (!mColorPalette)
  286. {
  287. llerrs << "Out of memory in LLImageBMP::updateData()" << llendl;
  288. return FALSE;
  289. }
  290. memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size ); /* Flawfinder: ignore */
  291. }
  292. return TRUE;
  293. }
  294. BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
  295. {
  296. llassert_always(raw_image);
  297. resetLastError();
  298. // Check to make sure that this instance has been initialized with data
  299. U8* mdata = getData();
  300. if (!mdata || (0 == getDataSize()))
  301. {
  302. setLastError("llimagebmp trying to decode an image with no data!");
  303. return FALSE;
  304. }
  305. raw_image->resize(getWidth(), getHeight(), 3);
  306. U8* src = mdata + mBitmapOffset;
  307. U8* dst = raw_image->getData();
  308. BOOL success = FALSE;
  309. switch( mBitsPerPixel )
  310. {
  311. case 8:
  312. if( mColorPaletteColors >= 256 )
  313. {
  314. success = decodeColorTable8( dst, src );
  315. }
  316. break;
  317. case 16:
  318. success = decodeColorMask16( dst, src );
  319. break;
  320. case 24:
  321. success = decodeTruecolor24( dst, src );
  322. break;
  323. case 32:
  324. success = decodeColorMask32( dst, src );
  325. break;
  326. }
  327. if( success && mOriginAtTop )
  328. {
  329. raw_image->verticalFlip();
  330. }
  331. return success;
  332. }
  333. U32 LLImageBMP::countTrailingZeros( U32 m )
  334. {
  335. U32 shift_count = 0;
  336. while( !(m & 1) )
  337. {
  338. shift_count++;
  339. m >>= 1;
  340. }
  341. return shift_count;
  342. }
  343. BOOL LLImageBMP::decodeColorMask16( U8* dst, U8* src )
  344. {
  345. llassert( 16 == mBitsPerPixel );
  346. if( !mBitfieldMask[0] && !mBitfieldMask[1] && !mBitfieldMask[2] )
  347. {
  348. // Use default values
  349. mBitfieldMask[0] = 0x00007C00;
  350. mBitfieldMask[1] = 0x000003E0;
  351. mBitfieldMask[2] = 0x0000001F;
  352. }
  353. S32 src_row_span = getWidth() * 2;
  354. S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
  355. U32 r_shift = countTrailingZeros( mBitfieldMask[2] );
  356. U32 g_shift = countTrailingZeros( mBitfieldMask[1] );
  357. U32 b_shift = countTrailingZeros( mBitfieldMask[0] );
  358. for( S32 row = 0; row < getHeight(); row++ )
  359. {
  360. for( S32 col = 0; col < getWidth(); col++ )
  361. {
  362. U32 value = *((U16*)src);
  363. dst[0] = U8((value & mBitfieldMask[2]) >> r_shift); // Red
  364. dst[1] = U8((value & mBitfieldMask[1]) >> g_shift); // Green
  365. dst[2] = U8((value & mBitfieldMask[0]) >> b_shift); // Blue
  366. src += 2;
  367. dst += 3;
  368. }
  369. src += alignment_bytes;
  370. }
  371. return TRUE;
  372. }
  373. BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src )
  374. {
  375. // Note: alpha is not supported
  376. llassert( 32 == mBitsPerPixel );
  377. if( !mBitfieldMask[0] && !mBitfieldMask[1] && !mBitfieldMask[2] )
  378. {
  379. // Use default values
  380. mBitfieldMask[0] = 0x00FF0000;
  381. mBitfieldMask[1] = 0x0000FF00;
  382. mBitfieldMask[2] = 0x000000FF;
  383. }
  384. S32 src_row_span = getWidth() * 4;
  385. S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
  386. U32 r_shift = countTrailingZeros( mBitfieldMask[0] );
  387. U32 g_shift = countTrailingZeros( mBitfieldMask[1] );
  388. U32 b_shift = countTrailingZeros( mBitfieldMask[2] );
  389. for( S32 row = 0; row < getHeight(); row++ )
  390. {
  391. for( S32 col = 0; col < getWidth(); col++ )
  392. {
  393. U32 value = *((U32*)src);
  394. dst[0] = U8((value & mBitfieldMask[0]) >> r_shift); // Red
  395. dst[1] = U8((value & mBitfieldMask[1]) >> g_shift); // Green
  396. dst[2] = U8((value & mBitfieldMask[2]) >> b_shift); // Blue
  397. src += 4;
  398. dst += 3;
  399. }
  400. src += alignment_bytes;
  401. }
  402. return TRUE;
  403. }
  404. BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src )
  405. {
  406. llassert( (8 == mBitsPerPixel) && (mColorPaletteColors >= 256) );
  407. S32 src_row_span = getWidth() * 1;
  408. S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
  409. for( S32 row = 0; row < getHeight(); row++ )
  410. {
  411. for( S32 col = 0; col < getWidth(); col++ )
  412. {
  413. S32 index = 4 * src[0];
  414. dst[0] = mColorPalette[index + 2]; // Red
  415. dst[1] = mColorPalette[index + 1]; // Green
  416. dst[2] = mColorPalette[index + 0]; // Blue
  417. src++;
  418. dst += 3;
  419. }
  420. src += alignment_bytes;
  421. }
  422. return TRUE;
  423. }
  424. BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
  425. {
  426. llassert( 24 == mBitsPerPixel );
  427. llassert( 3 == getComponents() );
  428. S32 src_row_span = getWidth() * 3;
  429. S32 alignment_bytes = (3 * src_row_span) % 4; // round up to nearest multiple of 4
  430. for( S32 row = 0; row < getHeight(); row++ )
  431. {
  432. for( S32 col = 0; col < getWidth(); col++ )
  433. {
  434. dst[0] = src[2]; // Red
  435. dst[1] = src[1]; // Green
  436. dst[2] = src[0]; // Blue
  437. src += 3;
  438. dst += 3;
  439. }
  440. src += alignment_bytes;
  441. }
  442. return TRUE;
  443. }
  444. BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
  445. {
  446. llassert_always(raw_image);
  447. resetLastError();
  448. S32 src_components = raw_image->getComponents();
  449. S32 dst_components = ( src_components < 3 ) ? 1 : 3;
  450. if( (2 == src_components) || (4 == src_components) )
  451. {
  452. llinfos << "Dropping alpha information during BMP encoding" << llendl;
  453. }
  454. setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components);
  455. U8 magic[14];
  456. LLBMPHeader header;
  457. int header_bytes = 14+sizeof(header);
  458. llassert(header_bytes == 54);
  459. if (getComponents() == 1)
  460. {
  461. header_bytes += 1024; // Need colour LUT.
  462. }
  463. int line_bytes = getComponents() * getWidth();
  464. int alignment_bytes = (3 * line_bytes) % 4;
  465. line_bytes += alignment_bytes;
  466. int file_bytes = line_bytes*getHeight() + header_bytes;
  467. // Allocate the new buffer for the data.
  468. if(!allocateData(file_bytes)) //memory allocation failed
  469. {
  470. return FALSE ;
  471. }
  472. magic[0] = 'B'; magic[1] = 'M';
  473. magic[2] = (U8) file_bytes;
  474. magic[3] = (U8)(file_bytes>>8);
  475. magic[4] = (U8)(file_bytes>>16);
  476. magic[5] = (U8)(file_bytes>>24);
  477. magic[6] = magic[7] = magic[8] = magic[9] = 0;
  478. magic[10] = (U8) header_bytes;
  479. magic[11] = (U8)(header_bytes>>8);
  480. magic[12] = (U8)(header_bytes>>16);
  481. magic[13] = (U8)(header_bytes>>24);
  482. header.mSize = 40;
  483. header.mWidth = getWidth();
  484. header.mHeight = getHeight();
  485. header.mPlanes = 1;
  486. header.mBitsPerPixel = (getComponents()==1)?8:24;
  487. header.mCompression = 0;
  488. header.mAlignmentPadding = 0;
  489. header.mImageSize = 0;
  490. #if LL_DARWIN
  491. header.mHorzPelsPerMeter = header.mVertPelsPerMeter = 2834; // 72dpi
  492. #else
  493. header.mHorzPelsPerMeter = header.mVertPelsPerMeter = 0;
  494. #endif
  495. header.mNumColors = header.mNumColorsImportant = 0;
  496. // convert BMP header to little endian (no-op on little endian builds)
  497. llendianswizzleone(header.mSize);
  498. llendianswizzleone(header.mWidth);
  499. llendianswizzleone(header.mHeight);
  500. llendianswizzleone(header.mPlanes);
  501. llendianswizzleone(header.mBitsPerPixel);
  502. llendianswizzleone(header.mCompression);
  503. llendianswizzleone(header.mAlignmentPadding);
  504. llendianswizzleone(header.mImageSize);
  505. llendianswizzleone(header.mHorzPelsPerMeter);
  506. llendianswizzleone(header.mVertPelsPerMeter);
  507. llendianswizzleone(header.mNumColors);
  508. llendianswizzleone(header.mNumColorsImportant);
  509. U8* mdata = getData();
  510. // Output magic, then header, then the palette table, then the data.
  511. U32 cur_pos = 0;
  512. memcpy(mdata, magic, 14);
  513. cur_pos += 14;
  514. memcpy(mdata+cur_pos, &header, 40); /* Flawfinder: ignore */
  515. cur_pos += 40;
  516. if (getComponents() == 1)
  517. {
  518. S32 n;
  519. for (n=0; n < 256; n++)
  520. {
  521. mdata[cur_pos++] = (U8)n;
  522. mdata[cur_pos++] = (U8)n;
  523. mdata[cur_pos++] = (U8)n;
  524. mdata[cur_pos++] = 0;
  525. }
  526. }
  527. // Need to iterate through, because we need to flip the RGB.
  528. const U8* src = raw_image->getData();
  529. U8* dst = mdata + cur_pos;
  530. for( S32 row = 0; row < getHeight(); row++ )
  531. {
  532. for( S32 col = 0; col < getWidth(); col++ )
  533. {
  534. switch( src_components )
  535. {
  536. case 1:
  537. *dst++ = *src++;
  538. break;
  539. case 2:
  540. {
  541. U32 lum = src[0];
  542. U32 alpha = src[1];
  543. *dst++ = (U8)(lum * alpha / 255);
  544. src += 2;
  545. break;
  546. }
  547. case 3:
  548. case 4:
  549. dst[0] = src[2];
  550. dst[1] = src[1];
  551. dst[2] = src[0];
  552. src += src_components;
  553. dst += 3;
  554. break;
  555. }
  556. }
  557. for( S32 i = 0; i < alignment_bytes; i++ )
  558. {
  559. *dst++ = 0;
  560. }
  561. }
  562. return TRUE;
  563. }