PageRenderTime 75ms CodeModel.GetById 2ms app.highlight 65ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llimage/llimagetga.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1185 lines | 885 code | 150 blank | 150 comment | 113 complexity | 3a1719a238f675dca6e29c06fd5cf6fe MD5 | raw file
   1/** 
   2 * @file llimagetga.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
  26#include "linden_common.h"
  27
  28#include "llimagetga.h"
  29
  30#include "lldir.h"
  31#include "llerror.h"
  32#include "llmath.h"
  33#include "llpointer.h"
  34
  35// For expanding 5-bit pixel values to 8-bit with best rounding
  36// static
  37const U8 LLImageTGA::s5to8bits[32] = 
  38	{
  39		0,   8,  16,  25,  33,  41,  49,  58,
  40	   66,  74,  82,  90,  99, 107, 115, 123,
  41	  132, 140, 148, 156, 165, 173, 181, 189,
  42	  197, 206, 214, 222, 230, 239, 247, 255
  43	};
  44
  45inline void LLImageTGA::decodeTruecolorPixel15( U8* dst, const U8* src )
  46{
  47    // We expand 5 bit data to 8 bit sample width.
  48    // The format of the 16-bit (LSB first) input word is
  49    // xRRRRRGGGGGBBBBB
  50	U32 t = U32(src[0]) + (U32(src[1]) << 8);
  51    dst[2] = s5to8bits[t & 0x1F];  // blue
  52    t >>= 5;
  53    dst[1] = s5to8bits[t & 0x1F];  // green
  54    t >>= 5;
  55    dst[0] = s5to8bits[t & 0x1F];  // red
  56}
  57
  58LLImageTGA::LLImageTGA() 
  59	: LLImageFormatted(IMG_CODEC_TGA),
  60	  mColorMap( NULL ),
  61	  mColorMapStart( 0 ),
  62	  mColorMapLength( 0 ),
  63	  mColorMapBytesPerEntry( 0 ),
  64	  mIs15Bit( FALSE ),
  65
  66	  mAttributeBits(0),
  67	  mColorMapDepth(0),
  68	  mColorMapIndexHi(0),
  69	  mColorMapIndexLo(0),
  70	  mColorMapLengthHi(0),
  71	  mColorMapLengthLo(0),
  72	  mColorMapType(0),
  73	  mDataOffset(0),
  74	  mHeightHi(0),
  75	  mHeightLo(0),
  76	  mIDLength(0),
  77	  mImageType(0),
  78	  mInterleave(0),
  79	  mOriginRightBit(0),
  80	  mOriginTopBit(0),
  81	  mPixelSize(0),
  82	  mWidthHi(0),
  83	  mWidthLo(0),
  84	  mXOffsetHi(0),
  85	  mXOffsetLo(0),
  86	  mYOffsetHi(0),
  87	  mYOffsetLo(0)
  88{
  89}
  90
  91LLImageTGA::LLImageTGA(const std::string& file_name) 
  92	: LLImageFormatted(IMG_CODEC_TGA),
  93	  mColorMap( NULL ),
  94	  mColorMapStart( 0 ),
  95	  mColorMapLength( 0 ),
  96	  mColorMapBytesPerEntry( 0 ),
  97	  mIs15Bit( FALSE )
  98{
  99	loadFile(file_name);
 100}
 101
 102LLImageTGA::~LLImageTGA()
 103{
 104	delete [] mColorMap;
 105}
 106
 107BOOL LLImageTGA::updateData()
 108{
 109	resetLastError();
 110
 111	// Check to make sure that this instance has been initialized with data
 112	if (!getData() || (0 == getDataSize()))
 113	{
 114		setLastError("LLImageTGA uninitialized");
 115		return FALSE;
 116	}
 117	
 118	// Pull image information from the header...
 119	U8	flags;
 120	U8	junk[256];
 121
 122	/****************************************************************************
 123	**
 124	**	For more information about the original Truevision TGA(tm) file format,
 125	**	or for additional information about the new extensions to the
 126	**	Truevision TGA file, refer to the "Truevision TGA File Format
 127	**	Specification Version 2.0" available from Truevision or your
 128	**	Truevision dealer.
 129	**
 130	**  FILE STRUCTURE FOR THE ORIGINAL TRUEVISION TGA FILE				
 131	**	  FIELD 1 :	NUMBER OF CHARACTERS IN ID FIELD (1 BYTES)	
 132	**	  FIELD 2 :	COLOR MAP TYPE (1 BYTES)			
 133	**	  FIELD 3 :	IMAGE TYPE CODE (1 BYTES)			
 134	**					= 0	NO IMAGE DATA INCLUDED		
 135	**					= 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
 136	**					= 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
 137	**					= 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
 138	**					= 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
 139	**					= 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
 140	**					= 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
 141	**	  FIELD 4 :	COLOR MAP SPECIFICATION	(5 BYTES)		
 142	**				4.1 : COLOR MAP ORIGIN (2 BYTES)	
 143	**				4.2 : COLOR MAP LENGTH (2 BYTES)	
 144	**				4.3 : COLOR MAP ENTRY SIZE (2 BYTES)	
 145	**	  FIELD 5 :	IMAGE SPECIFICATION (10 BYTES)			
 146	**				5.1 : X-ORIGIN OF IMAGE (2 BYTES)	
 147	**				5.2 : Y-ORIGIN OF IMAGE (2 BYTES)	
 148	**				5.3 : WIDTH OF IMAGE (2 BYTES)		
 149	**				5.4 : HEIGHT OF IMAGE (2 BYTES)		
 150	**				5.5 : IMAGE PIXEL SIZE (1 BYTE)		
 151	**				5.6 : IMAGE DESCRIPTOR BYTE (1 BYTE) 	
 152	**	  FIELD 6 :	IMAGE ID FIELD (LENGTH SPECIFIED BY FIELD 1)	
 153	**	  FIELD 7 :	COLOR MAP DATA (BIT WIDTH SPECIFIED BY FIELD 4.3 AND
 154	**				NUMBER OF COLOR MAP ENTRIES SPECIFIED IN FIELD 4.2)
 155	**	  FIELD 8 :	IMAGE DATA FIELD (WIDTH AND HEIGHT SPECIFIED IN
 156	**				FIELD 5.3 AND 5.4)				
 157	****************************************************************************/
 158
 159	mDataOffset = 0;
 160	mIDLength = *(getData()+mDataOffset++);
 161	mColorMapType = *(getData()+mDataOffset++);
 162	mImageType = *(getData()+mDataOffset++);
 163	mColorMapIndexLo = *(getData()+mDataOffset++);
 164	mColorMapIndexHi = *(getData()+mDataOffset++);
 165	mColorMapLengthLo = *(getData()+mDataOffset++);
 166	mColorMapLengthHi = *(getData()+mDataOffset++);
 167	mColorMapDepth = *(getData()+mDataOffset++);
 168	mXOffsetLo = *(getData()+mDataOffset++);
 169	mXOffsetHi = *(getData()+mDataOffset++);
 170	mYOffsetLo = *(getData()+mDataOffset++);
 171	mYOffsetHi = *(getData()+mDataOffset++);
 172	mWidthLo = *(getData()+mDataOffset++);
 173	mWidthHi = *(getData()+mDataOffset++);
 174	mHeightLo = *(getData()+mDataOffset++);
 175	mHeightHi = *(getData()+mDataOffset++);
 176	mPixelSize = *(getData()+mDataOffset++);
 177	flags = *(getData()+mDataOffset++);
 178	mAttributeBits = flags & 0xf;
 179	mOriginRightBit = (flags & 0x10) >> 4;
 180	mOriginTopBit = (flags & 0x20) >> 5;
 181	mInterleave = (flags & 0xc0) >> 6;
 182
 183	switch( mImageType )
 184	{
 185	case 0:
 186		// No image data included in file
 187		setLastError("Unable to load file.  TGA file contains no image data.");
 188		return FALSE;
 189	case 1:
 190		// Colormapped uncompressed
 191		if( 8 != mPixelSize )
 192		{
 193			setLastError("Unable to load file.  Colormapped images must have 8 bits per pixel.");
 194			return FALSE;
 195		}
 196		break;
 197	case 2:
 198		// Truecolor uncompressed
 199		break;
 200	case 3:
 201		// Monochrome uncompressed
 202		if( 8 != mPixelSize )
 203		{
 204			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
 205			return FALSE;
 206		}
 207		break;
 208	case 9:
 209		// Colormapped, RLE
 210		break;
 211	case 10:
 212		// Truecolor, RLE
 213		break;
 214	case 11:
 215		// Monochrome, RLE
 216		if( 8 != mPixelSize )
 217		{
 218			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
 219			return FALSE;
 220		}
 221		break;
 222	default:
 223		setLastError("Unable to load file.  Unrecoginzed TGA image type.");
 224		return FALSE;
 225	}
 226
 227	// discard the ID field, if any
 228	if (mIDLength)
 229	{
 230		memcpy(junk, getData()+mDataOffset, mIDLength);	/* Flawfinder: ignore */
 231		mDataOffset += mIDLength;
 232	}
 233	
 234	// check to see if there's a colormap since even rgb files can have them
 235	S32 color_map_bytes = 0;
 236	if( (1 == mColorMapType) && (mColorMapDepth > 0) )
 237	{
 238		mColorMapStart = (S32(mColorMapIndexHi) << 8) + mColorMapIndexLo;
 239		mColorMapLength = (S32(mColorMapLengthHi) << 8) + mColorMapLengthLo;
 240		
 241		if( mColorMapDepth > 24 )
 242		{
 243			mColorMapBytesPerEntry = 4;
 244		}
 245		else
 246		if( mColorMapDepth > 16 )
 247		{
 248			mColorMapBytesPerEntry = 3;
 249		}
 250		else
 251		if( mColorMapDepth > 8 )
 252		{
 253			mColorMapBytesPerEntry = 2;
 254		}
 255		else
 256		{
 257			mColorMapBytesPerEntry = 1;
 258		}
 259		color_map_bytes = mColorMapLength * mColorMapBytesPerEntry;
 260
 261		// Note: although it's legal for TGA files to have color maps and not use them
 262		// (some programs actually do this and use the color map for other ends), we'll
 263		// only allocate memory for one if _we_ intend to use it.
 264		if ( (1 == mImageType) || (9 == mImageType)  )
 265		{
 266			mColorMap = new U8[ color_map_bytes ];  
 267			if (!mColorMap)
 268			{
 269				llerrs << "Out of Memory in BOOL LLImageTGA::updateData()" << llendl;
 270				return FALSE;
 271			}
 272			memcpy( mColorMap, getData() + mDataOffset, color_map_bytes );	/* Flawfinder: ignore */
 273		}
 274
 275		mDataOffset += color_map_bytes;
 276	}
 277
 278	// heights are read as bytes to prevent endian problems
 279	S32 height = (S32(mHeightHi) << 8) + mHeightLo;
 280	S32 width = (S32(mWidthHi) << 8) + mWidthLo;
 281
 282	// make sure that it's a pixel format that we understand
 283	S32 bits_per_pixel;
 284	if( mColorMap )
 285	{
 286		bits_per_pixel = mColorMapDepth;
 287	}
 288	else
 289	{
 290		bits_per_pixel = mPixelSize;
 291	}
 292
 293	S32 components;
 294	switch(bits_per_pixel)
 295	{
 296	case 24:
 297		components = 3;
 298		break;
 299	case 32:
 300		components = 4;
 301//		Don't enforce this.  ACDSee doesn't bother to set the attributes bits correctly. Arrgh!
 302//		if( mAttributeBits != 8 )
 303//		{
 304//			setLastError("Unable to load file. 32 bit TGA image does not have 8 bits of alpha.");
 305//			return FALSE;
 306//		}
 307		mAttributeBits = 8;
 308		break;
 309	case 15:
 310	case 16:
 311		components = 3;
 312		mIs15Bit = TRUE;  // 16th bit is used for Targa hardware interupts and is ignored.
 313		break;
 314	case 8:
 315		components = 1;
 316		break;
 317	default:
 318		setLastError("Unable to load file. Unknown pixel size.");
 319		return FALSE;
 320	}
 321	setSize(width, height, components);
 322	
 323	return TRUE;
 324}
 325
 326BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
 327{
 328	llassert_always(raw_image);
 329	
 330	// Check to make sure that this instance has been initialized with data
 331	if (!getData() || (0 == getDataSize()))
 332	{
 333		setLastError("LLImageTGA trying to decode an image with no data!");
 334		return FALSE;
 335	}
 336
 337	// Copy everything after the header.
 338
 339	raw_image->resize(getWidth(), getHeight(), getComponents());
 340
 341	if( (getComponents() != 1) &&
 342		(getComponents() != 3) &&
 343		(getComponents() != 4) )
 344	{
 345		setLastError("TGA images with a number of components other than 1, 3, and 4 are not supported.");
 346		return FALSE;
 347	}
 348
 349
 350	if( mOriginRightBit )
 351	{
 352		setLastError("TGA images with origin on right side are not supported.");
 353		return FALSE;
 354	}
 355
 356	BOOL flipped = (mOriginTopBit != 0);
 357	BOOL rle_compressed = ((mImageType & 0x08) != 0);
 358
 359	if( mColorMap )
 360	{
 361		return decodeColorMap( raw_image, rle_compressed, flipped );
 362	}
 363	else
 364	{
 365		return decodeTruecolor( raw_image, rle_compressed, flipped );
 366	}
 367}
 368
 369BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
 370{
 371	BOOL success = FALSE;
 372	BOOL alpha_opaque = FALSE;
 373	if( rle )
 374	{
 375
 376		switch( getComponents() )
 377		{
 378		case 1:
 379			success = decodeTruecolorRle8( raw_image );
 380			break;
 381		case 3:
 382			if( mIs15Bit )
 383			{
 384				success = decodeTruecolorRle15( raw_image );
 385			}
 386			else
 387			{
 388				success = decodeTruecolorRle24( raw_image );
 389			}
 390			break;
 391		case 4:
 392			success = decodeTruecolorRle32( raw_image, alpha_opaque );
 393			if (alpha_opaque)
 394			{
 395				// alpha was entirely opaque
 396				// convert to 24 bit image
 397				LLPointer<LLImageRaw> compacted_image = new LLImageRaw(raw_image->getWidth(), raw_image->getHeight(), 3);
 398				compacted_image->copy(raw_image);
 399				raw_image->resize(raw_image->getWidth(), raw_image->getHeight(), 3);
 400				raw_image->copy(compacted_image);
 401			}
 402			break;
 403		}
 404	}
 405	else
 406	{
 407		BOOL alpha_opaque;
 408		success = decodeTruecolorNonRle( raw_image, alpha_opaque );
 409		if (alpha_opaque && raw_image->getComponents() == 4)
 410		{
 411			// alpha was entirely opaque
 412			// convert to 24 bit image
 413			LLPointer<LLImageRaw> compacted_image = new LLImageRaw(raw_image->getWidth(), raw_image->getHeight(), 3);
 414			compacted_image->copy(raw_image);
 415			raw_image->resize(raw_image->getWidth(), raw_image->getHeight(), 3);
 416			raw_image->copy(compacted_image);
 417		}
 418	}
 419	
 420	if( success && flipped )
 421	{
 422		// This works because the Targa definition requires that RLE blocks never
 423		// encode pixels from more than one scanline.
 424		// (On the other hand, it's not as fast as writing separate flipped versions as 
 425		// we did with TruecolorNonRle.)
 426		raw_image->verticalFlip();
 427	}
 428
 429	return success;
 430}
 431
 432
 433BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaque )
 434{
 435	alpha_opaque = TRUE;
 436
 437	// Origin is the bottom left
 438	U8* dst = raw_image->getData();
 439	U8* src = getData() + mDataOffset;
 440	S32 pixels = getWidth() * getHeight();
 441
 442	if (getComponents() == 4)
 443	{
 444		while( pixels-- )
 445		{
 446			// Our data is stored in RGBA.  TGA stores them as BGRA (little-endian ARGB)
 447			dst[0] = src[2]; // Red
 448			dst[1] = src[1]; // Green
 449			dst[2] = src[0]; // Blue
 450			dst[3] = src[3]; // Alpha
 451			if (dst[3] != 255)
 452			{
 453				alpha_opaque = FALSE;
 454			}
 455			dst += 4;
 456			src += 4;
 457		}
 458	}
 459	else if (getComponents() == 3)
 460	{
 461		if( mIs15Bit )
 462		{
 463			while( pixels-- )
 464			{
 465				decodeTruecolorPixel15( dst, src );
 466				dst += 3;
 467				src += 2;
 468			}
 469		}
 470		else
 471		{
 472			while( pixels-- )
 473			{
 474				dst[0] = src[2]; // Red
 475				dst[1] = src[1]; // Green
 476				dst[2] = src[0]; // Blue
 477				dst += 3;
 478				src += 3;
 479			}
 480		}
 481	}
 482	else if (getComponents() == 1)
 483	{
 484		memcpy(dst, src, pixels);	/* Flawfinder: ignore */
 485	}
 486
 487	return TRUE;
 488}
 489
 490void LLImageTGA::decodeColorMapPixel8( U8* dst, const U8* src )
 491{
 492	S32 index = llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 );
 493	dst[0] = mColorMap[ index ];
 494}
 495
 496void LLImageTGA::decodeColorMapPixel15( U8* dst, const U8* src )
 497{
 498	S32 index = llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 );
 499	decodeTruecolorPixel15( dst, mColorMap + 2 * index );
 500}
 501
 502void LLImageTGA::decodeColorMapPixel24( U8* dst, const U8* src )
 503{
 504	S32 index = 3 * llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 );
 505	dst[0] = mColorMap[ index + 2 ];	// Red
 506	dst[1] = mColorMap[ index + 1 ];	// Green
 507	dst[2] = mColorMap[ index + 0 ];	// Blue
 508}
 509
 510void LLImageTGA::decodeColorMapPixel32( U8* dst, const U8* src )
 511{
 512	S32 index = 4 * llclamp( *src - mColorMapStart, 0, mColorMapLength - 1 );
 513	dst[0] = mColorMap[ index + 2 ];	// Red
 514	dst[1] = mColorMap[ index + 1 ];	// Green
 515	dst[2] = mColorMap[ index + 0 ];	// Blue
 516	dst[3] = mColorMap[ index + 3 ];	// Alpha
 517}
 518
 519
 520BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
 521{
 522	// If flipped, origin is the top left.  Need to reverse the order of the rows.
 523	// Otherwise the origin is the bottom left.
 524
 525	if( 8 != mPixelSize )
 526	{
 527		return FALSE;
 528	}
 529
 530	U8* src = getData() + mDataOffset;
 531	U8* dst = raw_image->getData();	// start from the top
 532	
 533	void (LLImageTGA::*pixel_decoder)( U8*, const U8* );
 534
 535	switch( mColorMapBytesPerEntry )
 536	{
 537		case 1:	pixel_decoder = &LLImageTGA::decodeColorMapPixel8;  break;
 538		case 2:	pixel_decoder = &LLImageTGA::decodeColorMapPixel15; break;
 539		case 3:	pixel_decoder = &LLImageTGA::decodeColorMapPixel24; break;
 540		case 4:	pixel_decoder = &LLImageTGA::decodeColorMapPixel32; break;
 541		default: llassert(0); return FALSE;
 542	}
 543
 544	if( rle )
 545	{
 546		U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1);
 547		while( dst <= last_dst )
 548		{
 549			// Read RLE block header
 550			U8 block_header_byte = *src;
 551			src++;
 552
 553			U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
 554			if( block_header_byte & 0x80 )
 555			{
 556				// Encoded (duplicate-pixel) block
 557				do
 558				{
 559					(this->*pixel_decoder)( dst, src );
 560					dst += getComponents();
 561					block_pixel_count--;
 562				}
 563				while( block_pixel_count > 0 );
 564				src++;
 565			}
 566			else 
 567			{
 568				// Unencoded block
 569				do
 570				{
 571					(this->*pixel_decoder)( dst, src );
 572					dst += getComponents();
 573					src++;
 574					block_pixel_count--;
 575				}
 576				while( block_pixel_count > 0 );
 577			}
 578		}
 579
 580		raw_image->verticalFlip();
 581	}
 582	else
 583	{
 584		S32 src_row_bytes = getWidth();
 585		S32 dst_row_bytes = getWidth() * getComponents();
 586
 587		if( flipped )
 588		{
 589			U8* src_last_row_start = src + (getHeight() - 1) * src_row_bytes;
 590			src = src_last_row_start;		// start from the bottom
 591			src_row_bytes *= -1;
 592		}
 593
 594
 595		S32 i;
 596		S32 j;
 597
 598		for( S32 row = 0; row < getHeight(); row++ )
 599		{
 600			for( i = 0, j = 0; j < getWidth(); i += getComponents(), j++ )
 601			{
 602				(this->*pixel_decoder)( dst + i, src + j );
 603			}
 604
 605			dst += dst_row_bytes;
 606			src += src_row_bytes;
 607		}
 608	}
 609
 610	return TRUE;
 611}
 612
 613
 614
 615BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
 616{
 617	llassert_always(raw_image);
 618	
 619	deleteData();
 620
 621	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
 622
 623	// Data from header
 624	mIDLength = 0;		// Length of identifier string
 625	mColorMapType = 0;	// 0 = No Map
 626
 627	// Supported: 2 = Uncompressed true color, 3 = uncompressed monochrome without colormap
 628	switch( getComponents() )
 629	{
 630	case 1:
 631		mImageType = 3;		
 632		break;
 633	case 2:	 // Interpret as intensity plus alpha
 634	case 3:
 635	case 4:
 636		mImageType = 2;		
 637		break;
 638	default:
 639		return FALSE;
 640	}
 641
 642	// Color map stuff (unsupported)
 643	mColorMapIndexLo = 0;		// First color map entry (low order byte)
 644	mColorMapIndexHi = 0;		// First color map entry (high order byte)
 645	mColorMapLengthLo = 0;		// Color map length (low order byte)
 646	mColorMapLengthHi = 0;		// Color map length (high order byte)
 647	mColorMapDepth = 0;	// Size of color map entry (15, 16, 24, or 32 bits)
 648
 649	// Image offset relative to origin.
 650	mXOffsetLo = 0;		// X offset from origin (low order byte)
 651	mXOffsetHi = 0;		// X offset from origin (hi order byte)
 652	mYOffsetLo = 0;		// Y offset from origin (low order byte)
 653	mYOffsetHi = 0;		// Y offset from origin (hi order byte)
 654
 655	// Height and width
 656	mWidthLo = U8(getWidth() & 0xFF);			// Width (low order byte)
 657	mWidthHi = U8((getWidth() >> 8) & 0xFF);	// Width (hi order byte)
 658	mHeightLo = U8(getHeight() & 0xFF);			// Height (low order byte)
 659	mHeightHi = U8((getHeight() >> 8) & 0xFF);	// Height (hi order byte)
 660
 661	S32 bytes_per_pixel;
 662	switch( getComponents() )
 663	{
 664	case 1:
 665		bytes_per_pixel = 1;		
 666		break;
 667	case 3:
 668		bytes_per_pixel = 3;		
 669		break;
 670	case 2:	 // Interpret as intensity plus alpha.  Store as RGBA.
 671	case 4:
 672		bytes_per_pixel = 4;		
 673		break;
 674	default:
 675		return FALSE;
 676	}
 677	mPixelSize = U8(bytes_per_pixel * 8);		// 8, 16, 24, 32 bits per pixel
 678
 679	mAttributeBits = (4 == bytes_per_pixel) ? 8 : 0;	// 4 bits: number of attribute bits (alpha) per pixel
 680	mOriginRightBit = 0;	// 1 bit: origin, 0 = left, 1 = right
 681	mOriginTopBit = 0;	// 1 bit: origin, 0 = bottom, 1 = top
 682	mInterleave = 0;	// 2 bits: interleaved flag, 0 = none, 1 = interleaved 2, 2 = interleaved 4
 683
 684
 685	const S32 TGA_HEADER_SIZE = 18;
 686	const S32 COLOR_MAP_SIZE = 0;
 687	mDataOffset = TGA_HEADER_SIZE + mIDLength + COLOR_MAP_SIZE; // Offset from start of data to the actual header.
 688
 689	S32 pixels = getWidth() * getHeight();
 690	S32 datasize = mDataOffset + bytes_per_pixel * pixels;
 691	U8* dst = allocateData(datasize);
 692
 693	// Write header
 694	*(dst++) = mIDLength;		
 695	*(dst++) = mColorMapType;	
 696	*(dst++) = mImageType;		
 697	*(dst++) = mColorMapIndexLo;		
 698	*(dst++) = mColorMapIndexHi;		
 699	*(dst++) = mColorMapLengthLo;		
 700	*(dst++) = mColorMapLengthHi;		
 701	*(dst++) = mColorMapDepth;	
 702	*(dst++) = mXOffsetLo;		
 703	*(dst++) = mXOffsetHi;		
 704	*(dst++) = mYOffsetLo;		
 705	*(dst++) = mYOffsetHi;		
 706	*(dst++) = mWidthLo;		
 707	*(dst++) = mWidthHi;		
 708	*(dst++) = mHeightLo;		
 709	*(dst++) = mHeightHi;		
 710	*(dst++) = mPixelSize;		
 711	*(dst++) =
 712		((mInterleave & 3) << 5) |
 713		((mOriginTopBit & 1) << 4) |
 714		((mOriginRightBit & 1) << 3) |
 715		((mAttributeBits & 0xF) << 0);	
 716
 717	// Write pixels
 718	const U8* src = raw_image->getData();
 719	llassert( dst == getData() + mDataOffset );
 720	S32 i = 0;
 721	S32 j = 0;
 722	switch( getComponents() )
 723	{
 724	case 1:
 725		memcpy( dst, src, bytes_per_pixel * pixels );	/* Flawfinder: ignore */
 726		break;
 727
 728	case 2:
 729		while( pixels-- )
 730		{
 731			dst[i + 0] = src[j + 0];	// intensity
 732			dst[i + 1] = src[j + 0];	// intensity
 733			dst[i + 2] = src[j + 0];	// intensity
 734			dst[i + 3] = src[j + 1];	// alpha
 735			i += 4;
 736			j += 2;
 737		}
 738		break;
 739
 740	case 3:
 741		while( pixels-- )
 742		{
 743			dst[i + 0] = src[i + 2];	// blue
 744			dst[i + 1] = src[i + 1];	// green
 745			dst[i + 2] = src[i + 0];	// red
 746			i += 3;
 747		}
 748		break;
 749
 750	case 4:
 751		while( pixels-- )
 752		{
 753			dst[i + 0] = src[i + 2];	// blue
 754			dst[i + 1] = src[i + 1];	// green
 755			dst[i + 2] = src[i + 0];	// red
 756			dst[i + 3] = src[i + 3];	// alpha
 757			i += 4;
 758		}
 759		break;
 760	}
 761	
 762	return TRUE;
 763}
 764
 765BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque )
 766{
 767	llassert( getComponents() == 4 );
 768	alpha_opaque = TRUE;
 769
 770	U8* dst = raw_image->getData();
 771	U32* dst_pixels = (U32*) dst;
 772
 773	U8* src = getData() + mDataOffset;
 774	U8* last_src = src + getDataSize();
 775
 776	U32 rgba;
 777	U8* rgba_byte_p = (U8*) &rgba;
 778
 779	U32* last_dst_pixel = dst_pixels + getHeight() * getWidth() - 1;
 780	while( dst_pixels <= last_dst_pixel )
 781	{
 782		// Read RLE block header
 783		
 784		if (src >= last_src)
 785			return FALSE;
 786
 787		U8 block_header_byte = *src;
 788		src++;
 789
 790		U32 block_pixel_count = (block_header_byte & 0x7F) + 1;
 791		if( block_header_byte & 0x80 )
 792		{
 793			// Encoded (duplicate-pixel) block
 794
 795			if (src + 3 >= last_src)
 796				return FALSE;
 797			
 798			rgba_byte_p[0] = src[2];
 799			rgba_byte_p[1] = src[1];
 800			rgba_byte_p[2] = src[0];
 801			rgba_byte_p[3] = src[3];
 802			if (rgba_byte_p[3] != 255)
 803			{
 804				alpha_opaque = FALSE;
 805			}
 806
 807			src += 4;
 808			register U32 value = rgba;
 809			do
 810			{
 811				*dst_pixels = value;
 812				dst_pixels++;
 813				block_pixel_count--;
 814			}
 815			while( block_pixel_count > 0 );
 816		}
 817		else 
 818		{
 819			// Unencoded block
 820			do
 821			{
 822				if (src + 3 >= last_src)
 823					return FALSE;
 824				
 825				((U8*)dst_pixels)[0] = src[2];
 826				((U8*)dst_pixels)[1] = src[1];
 827				((U8*)dst_pixels)[2] = src[0];
 828				((U8*)dst_pixels)[3] = src[3];
 829				if (src[3] != 255)
 830				{
 831					alpha_opaque = FALSE;
 832				}
 833				src += 4;
 834				dst_pixels++;
 835				block_pixel_count--;
 836			}
 837			while( block_pixel_count > 0 );
 838		}
 839	}
 840
 841	return TRUE; 
 842}
 843
 844BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 845{
 846	llassert( getComponents() == 3 );
 847	llassert( mIs15Bit );
 848
 849	U8* dst = raw_image->getData();
 850	U8* src = getData() + mDataOffset;
 851
 852	U8* last_src = src + getDataSize();
 853	U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1);
 854
 855	while( dst <= last_dst )
 856	{
 857		// Read RLE block header
 858
 859		if (src >= last_src)
 860			return FALSE;
 861
 862		U8 block_header_byte = *src;
 863		src++;
 864
 865		U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
 866		if( block_header_byte & 0x80 )
 867		{
 868			// Encoded (duplicate-pixel) block
 869			do
 870			{
 871				if (src + 2 >= last_src)
 872					return FALSE;
 873				
 874				decodeTruecolorPixel15( dst, src );   // slow
 875				dst += 3;
 876				block_pixel_count--;
 877			}
 878			while( block_pixel_count > 0 );
 879			src += 2;
 880		}
 881		else 
 882		{
 883			// Unencoded block
 884			do
 885			{
 886				if (src + 2 >= last_src)
 887					return FALSE;
 888
 889				decodeTruecolorPixel15( dst, src );
 890				dst += 3;
 891				src += 2;
 892				block_pixel_count--;
 893			}
 894			while( block_pixel_count > 0 );
 895		}
 896	}
 897
 898	return TRUE;
 899}
 900
 901
 902
 903BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 904{
 905	llassert( getComponents() == 3 );
 906
 907	U8* dst = raw_image->getData();
 908	U8* src = getData() + mDataOffset;
 909
 910	U8* last_src = src + getDataSize();
 911	U8* last_dst = dst + getComponents() * (getHeight() * getWidth() - 1);
 912
 913	while( dst <= last_dst )
 914	{
 915		// Read RLE block header
 916
 917		if (src >= last_src)
 918			return FALSE;
 919	
 920		U8 block_header_byte = *src;
 921		src++;
 922
 923		U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
 924		if( block_header_byte & 0x80 )
 925		{
 926			// Encoded (duplicate-pixel) block
 927			do
 928			{
 929				if (src + 2 >= last_src)
 930					return FALSE;
 931				dst[0] = src[2];
 932				dst[1] = src[1];
 933				dst[2] = src[0];
 934				dst += 3;
 935				block_pixel_count--;
 936			}
 937			while( block_pixel_count > 0 );
 938			src += 3;
 939		}
 940		else 
 941		{
 942			// Unencoded block
 943			do
 944			{
 945				if (src + 2 >= last_src)
 946					return FALSE;
 947				
 948				dst[0] = src[2];
 949				dst[1] = src[1];
 950				dst[2] = src[0];
 951				dst += 3;
 952				src += 3;
 953				block_pixel_count--;
 954			}
 955			while( block_pixel_count > 0 );
 956		}
 957	}
 958
 959	return TRUE;
 960}
 961
 962
 963BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 964{
 965	llassert( getComponents() == 1 );
 966
 967	U8* dst = raw_image->getData();
 968	U8* src = getData() + mDataOffset;
 969
 970	U8* last_src = src + getDataSize();
 971	U8* last_dst = dst + getHeight() * getWidth() - 1;
 972	
 973	while( dst <= last_dst )
 974	{
 975		// Read RLE block header
 976
 977		if (src >= last_src)
 978			return FALSE;
 979
 980		U8 block_header_byte = *src;
 981		src++;
 982
 983		U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
 984		if( block_header_byte & 0x80 )
 985		{
 986			if (src >= last_src)
 987				return FALSE;
 988			
 989			// Encoded (duplicate-pixel) block
 990			memset( dst, *src, block_pixel_count );
 991			dst += block_pixel_count;
 992			src++;
 993		}
 994		else 
 995		{
 996			// Unencoded block
 997			do
 998			{
 999				if (src >= last_src)
1000					return FALSE;
1001				
1002				*dst = *src;
1003				dst++;
1004				src++;
1005				block_pixel_count--;
1006			}
1007			while( block_pixel_count > 0 );
1008		}
1009	}
1010
1011	return TRUE;
1012}
1013
1014
1015// Decoded and process the image for use in avatar gradient masks.
1016// Processing happens during the decode for speed.
1017BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight )
1018{
1019	llassert_always(raw_image);
1020	
1021	// "Domain" isn't really the right word.  It refers to the width of the 
1022	// ramp portion of the function that relates input and output pixel values.
1023	// A domain of 0 gives a step function.
1024	// 
1025	//   |                      /----------------
1026	//  O|                     / |
1027	//  u|                    /  |
1028	//  t|                   /   |
1029	//	p|------------------/    |
1030	//  u|                  |    | 
1031	//  t|<---------------->|<-->|
1032	//	 |  "offset"         "domain"
1033	//   |
1034	// --+---Input--------------------------------
1035	//   |
1036
1037	if (!getData() || (0 == getDataSize()))
1038	{
1039		setLastError("LLImageTGA trying to decode an image with no data!");
1040		return FALSE;
1041	}
1042
1043	// Only works for unflipped monochrome RLE images
1044	if( (getComponents() != 1) || (mImageType != 11) || mOriginTopBit || mOriginRightBit ) 
1045	{
1046		llerrs << "LLImageTGA trying to alpha-gradient process an image that's not a standard RLE, one component image" << llendl;
1047		return FALSE;
1048	}
1049
1050	raw_image->resize(getWidth(), getHeight(), getComponents());
1051
1052	U8* dst = raw_image->getData();
1053	U8* src = getData() + mDataOffset;
1054	U8* last_dst = dst + getHeight() * getWidth() - 1;
1055
1056	if( domain > 0 )
1057	{
1058		// Process using a look-up table (lut)
1059		const S32 LUT_LEN = 256;
1060		U8 lut[LUT_LEN];
1061		S32 i;
1062
1063		F32 scale = 1.f / domain;
1064		F32 offset = (1.f - domain) * llclampf( 1.f - weight );
1065		F32 bias = -(scale * offset);
1066		
1067		for( i = 0; i < LUT_LEN; i++ )
1068		{
1069			lut[i] = (U8)llclampb( 255.f * ( i/255.f * scale + bias ) );
1070		}
1071
1072		while( dst <= last_dst )
1073		{
1074			// Read RLE block header
1075			U8 block_header_byte = *src;
1076			src++;
1077
1078			U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
1079			if( block_header_byte & 0x80 )
1080			{
1081				// Encoded (duplicate-pixel) block
1082				memset( dst, lut[ *src ], block_pixel_count );
1083				dst += block_pixel_count;
1084				src++;
1085			}
1086			else 
1087			{
1088				// Unencoded block
1089				do
1090				{
1091					*dst = lut[ *src ];
1092					dst++;
1093					src++;
1094					block_pixel_count--;
1095				}
1096				while( block_pixel_count > 0 );
1097			}
1098		}
1099	}
1100	else
1101	{
1102		// Process using a simple comparison agains a threshold
1103		const U8 threshold = (U8)(0xFF * llclampf( 1.f - weight ));
1104
1105		while( dst <= last_dst )
1106		{
1107			// Read RLE block header
1108			U8 block_header_byte = *src;
1109			src++;
1110
1111			U8 block_pixel_count = (block_header_byte & 0x7F) + 1;
1112			if( block_header_byte & 0x80 )
1113			{
1114				// Encoded (duplicate-pixel) block
1115				memset( dst, ((*src >= threshold) ? 0xFF : 0), block_pixel_count );
1116				dst += block_pixel_count;
1117				src++;
1118			}
1119			else 
1120			{
1121				// Unencoded block
1122				do
1123				{
1124					*dst = (*src >= threshold) ? 0xFF : 0;
1125					dst++;
1126					src++;
1127					block_pixel_count--;
1128				}
1129				while( block_pixel_count > 0 );
1130			}
1131		}
1132	}
1133	return TRUE;
1134}
1135
1136// Reads a .tga file and creates an LLImageTGA with its data.
1137bool LLImageTGA::loadFile( const std::string& path )
1138{
1139	S32 len = path.size();
1140	if( len < 5 )
1141	{
1142		return false;
1143	}
1144	
1145	std::string extension = gDirUtilp->getExtension(path);
1146	if( "tga" != extension )
1147	{
1148		return false;
1149	}
1150	
1151	LLFILE* file = LLFile::fopen(path, "rb");	/* Flawfinder: ignore */
1152	if( !file )
1153	{
1154		llwarns << "Couldn't open file " << path << llendl;
1155		return false;
1156	}
1157
1158	S32 file_size = 0;
1159	if (!fseek(file, 0, SEEK_END))
1160	{
1161		file_size = ftell(file);
1162		fseek(file, 0, SEEK_SET);
1163	}
1164
1165	U8* buffer = allocateData(file_size);
1166	S32 bytes_read = fread(buffer, 1, file_size, file);
1167	if( bytes_read != file_size )
1168	{
1169		deleteData();
1170		llwarns << "Couldn't read file " << path << llendl;
1171		return false;
1172	}
1173
1174	fclose( file );
1175
1176	if( !updateData() )
1177	{
1178		llwarns << "Couldn't decode file " << path << llendl;
1179		deleteData();
1180		return false;
1181	}
1182	return true;
1183}
1184
1185