llimagebmp.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:15k
源码类别:

游戏引擎

开发平台:

C++ Builder

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