PageRenderTime 43ms CodeModel.GetById 20ms app.highlight 9ms RepoModel.GetById 11ms app.codeStats 0ms

/indra/llimage/llimagepng.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 136 lines | 68 code | 23 blank | 45 comment | 9 complexity | 9f38e6c41182eadf7b62e6ce533c5930 MD5 | raw file
  1/*
  2 * @file llimagepng.cpp
  3 * @brief LLImageFormatted glue to encode / decode PNG files.
  4 *
  5 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28#include "stdtypes.h"
 29#include "llerror.h"
 30
 31#include "llimage.h"
 32#include "llpngwrapper.h"
 33#include "llimagepng.h"
 34
 35// ---------------------------------------------------------------------------
 36// LLImagePNG
 37// ---------------------------------------------------------------------------
 38LLImagePNG::LLImagePNG()
 39    : LLImageFormatted(IMG_CODEC_PNG)
 40{
 41}
 42
 43LLImagePNG::~LLImagePNG()
 44{
 45}
 46
 47// Virtual
 48// Parse PNG image information and set the appropriate
 49// width, height and component (channel) information.
 50BOOL LLImagePNG::updateData()
 51{
 52    resetLastError();
 53
 54    // Check to make sure that this instance has been initialized with data
 55    if (!getData() || (0 == getDataSize()))
 56    {
 57        setLastError("Uninitialized instance of LLImagePNG");
 58        return FALSE;
 59    }
 60
 61	// Decode the PNG data and extract sizing information
 62	LLPngWrapper pngWrapper;
 63	LLPngWrapper::ImageInfo infop;
 64	if (! pngWrapper.readPng(getData(), NULL, &infop))
 65	{
 66		setLastError(pngWrapper.getErrorMessage());
 67		return FALSE;
 68	}
 69
 70	setSize(infop.mWidth, infop.mHeight, infop.mComponents);
 71
 72	return TRUE;
 73}
 74
 75// Virtual
 76// Decode an in-memory PNG image into the raw RGB or RGBA format
 77// used within SecondLife.
 78BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
 79{
 80	llassert_always(raw_image);
 81
 82    resetLastError();
 83
 84    // Check to make sure that this instance has been initialized with data
 85    if (!getData() || (0 == getDataSize()))
 86    {
 87        setLastError("LLImagePNG trying to decode an image with no data!");
 88        return FALSE;
 89    }
 90
 91	// Decode the PNG data into the raw image
 92	LLPngWrapper pngWrapper;
 93	if (! pngWrapper.readPng(getData(), raw_image))
 94	{
 95		setLastError(pngWrapper.getErrorMessage());
 96		return FALSE;
 97	}
 98
 99	return TRUE;
100}
101
102// Virtual
103// Encode the in memory RGB image into PNG format.
104BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
105{
106	llassert_always(raw_image);
107
108    resetLastError();
109
110	// Image logical size
111	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
112
113	// Temporary buffer to hold the encoded image. Note: the final image
114	// size should be much smaller due to compression.
115	U32 bufferSize = getWidth() * getHeight() * getComponents() + 1024;
116    U8* tmpWriteBuffer = new U8[ bufferSize ];
117
118	// Delegate actual encoding work to wrapper
119	LLPngWrapper pngWrapper;
120	if (! pngWrapper.writePng(raw_image, tmpWriteBuffer))
121	{
122		setLastError(pngWrapper.getErrorMessage());
123		delete[] tmpWriteBuffer;
124		return FALSE;
125	}
126
127	// Resize internal buffer and copy from temp
128	U32 encodedSize = pngWrapper.getFinalSize();
129	allocateData(encodedSize);
130	memcpy(getData(), tmpWriteBuffer, encodedSize);
131
132	delete[] tmpWriteBuffer;
133
134	return TRUE;
135}
136