STORM-151 : Remove files we have no use of
parent
e043207cd7
commit
2ea7b1a05e
|
|
@ -1,162 +0,0 @@
|
|||
/**
|
||||
* @file llblockdata.cpp
|
||||
* @brief Image block structure
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llblockdata.h"
|
||||
#include "llmath.h"
|
||||
|
||||
LLBlockData::LLBlockData(const U32 type)
|
||||
{
|
||||
mType = type;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mRowStride = 0;
|
||||
mData = NULL;
|
||||
}
|
||||
|
||||
void LLBlockData::setData(U8 *data, const U32 width, const U32 height, const U32 row_stride)
|
||||
{
|
||||
mData = data;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
if (row_stride)
|
||||
{
|
||||
mRowStride = row_stride;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRowStride = width * 4;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLBlockData::getType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
|
||||
U8 *LLBlockData::getData() const
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
U32 LLBlockData::getSize() const
|
||||
{
|
||||
return mWidth*mHeight;
|
||||
}
|
||||
|
||||
U32 LLBlockData::getWidth() const
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
U32 LLBlockData::getHeight() const
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
U32 LLBlockData::getRowStride() const
|
||||
{
|
||||
return mRowStride;
|
||||
}
|
||||
|
||||
LLBlockDataU32::LLBlockDataU32() : LLBlockData(BLOCK_TYPE_U32)
|
||||
{
|
||||
mPrecision = 32;
|
||||
}
|
||||
|
||||
void LLBlockDataU32::setData(U32 *data, const U32 width, const U32 height, const U32 row_stride)
|
||||
{
|
||||
LLBlockData::setData((U8 *)data, width, height, row_stride);
|
||||
}
|
||||
|
||||
U32 LLBlockDataU32::getSize() const
|
||||
{
|
||||
return mWidth*mHeight*4;
|
||||
}
|
||||
|
||||
void LLBlockDataU32::setPrecision(const U32 bits)
|
||||
{
|
||||
mPrecision = bits;
|
||||
}
|
||||
|
||||
U32 LLBlockDataU32::getPrecision() const
|
||||
{
|
||||
return mPrecision;
|
||||
}
|
||||
|
||||
void LLBlockDataF32::setPrecision(const U32 bits)
|
||||
{
|
||||
mPrecision = bits;
|
||||
}
|
||||
|
||||
U32 LLBlockDataF32::getPrecision() const
|
||||
{
|
||||
return mPrecision;
|
||||
}
|
||||
|
||||
void LLBlockDataF32::setData(F32 *data, const U32 width, const U32 height, const U32 row_stride)
|
||||
{
|
||||
LLBlockData::setData((U8 *)data, width, height, row_stride);
|
||||
}
|
||||
|
||||
void LLBlockDataF32::setMin(const F32 min)
|
||||
{
|
||||
mMin = min;
|
||||
}
|
||||
|
||||
void LLBlockDataF32::setMax(const F32 max)
|
||||
{
|
||||
mMax = max;
|
||||
}
|
||||
|
||||
void LLBlockDataF32::calcMinMax()
|
||||
{
|
||||
U32 x, y;
|
||||
|
||||
mMin = *(F32*)mData;
|
||||
mMax = mMin;
|
||||
|
||||
for (y = 0; y < mHeight; y++)
|
||||
{
|
||||
for (x = 0; x < mWidth; x++)
|
||||
{
|
||||
F32 data = *(F32*)(mData + y*mRowStride + x*4);
|
||||
mMin = llmin(data, mMin);
|
||||
mMax = llmax(data, mMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
F32 LLBlockDataF32::getMin() const
|
||||
{
|
||||
return mMin;
|
||||
}
|
||||
|
||||
F32 LLBlockDataF32::getMax() const
|
||||
{
|
||||
return mMax;
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/**
|
||||
* @file llblockdata.h
|
||||
* @brief Image block structure
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLBLOCKDATA_H
|
||||
#define LL_LLBLOCKDATA_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//
|
||||
// This class stores all of the information about
|
||||
// a single channel of raw data, either integer
|
||||
// or floating point.
|
||||
//
|
||||
class LLBlockData
|
||||
{
|
||||
protected:
|
||||
U32 mType;
|
||||
U32 mWidth;
|
||||
U32 mHeight;
|
||||
U32 mRowStride;
|
||||
U8 *mData;
|
||||
public:
|
||||
enum
|
||||
{
|
||||
BLOCK_TYPE_U32 = 1,
|
||||
BLOCK_TYPE_F32 = 2
|
||||
};
|
||||
|
||||
LLBlockData(const U32 type);
|
||||
virtual ~LLBlockData() {}
|
||||
|
||||
void setData(U8 *data, const U32 width, const U32 height, const U32 row_stride = 0);
|
||||
|
||||
U32 getType() const;
|
||||
U8 *getData() const;
|
||||
virtual U32 getSize() const;
|
||||
U32 getWidth() const;
|
||||
U32 getHeight() const;
|
||||
U32 getRowStride() const;
|
||||
};
|
||||
|
||||
class LLBlockDataU32 : public LLBlockData
|
||||
{
|
||||
protected:
|
||||
U32 mPrecision;
|
||||
public:
|
||||
LLBlockDataU32();
|
||||
|
||||
void setData(U32 *data, const U32 width, const U32 height, const U32 row_stride = 0);
|
||||
void setPrecision(const U32 bits);
|
||||
|
||||
/*virtual*/ U32 getSize() const;
|
||||
U32 getPrecision() const;
|
||||
};
|
||||
|
||||
class LLBlockDataF32 : public LLBlockData
|
||||
{
|
||||
protected:
|
||||
U32 mPrecision;
|
||||
F32 mMin;
|
||||
F32 mMax;
|
||||
public:
|
||||
LLBlockDataF32()
|
||||
: LLBlockData(LLBlockData::BLOCK_TYPE_F32),
|
||||
mPrecision(0),
|
||||
mMin(0.f),
|
||||
mMax(0.f)
|
||||
{};
|
||||
|
||||
void setData(F32 *data, const U32 width, const U32 height, const U32 row_stride = 0);
|
||||
|
||||
void setPrecision(const U32 bits);
|
||||
void setMin(const F32 min);
|
||||
void setMax(const F32 max);
|
||||
|
||||
void calcMinMax();
|
||||
|
||||
U32 getPrecision() const;
|
||||
F32 getMin() const;
|
||||
F32 getMax() const;
|
||||
};
|
||||
|
||||
#endif // LL_LLBLOCKDATA_H
|
||||
|
|
@ -1,270 +0,0 @@
|
|||
/**
|
||||
* @file llblockdecoder.cpp
|
||||
* @brief Image block decompression
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llblockdecoder.h"
|
||||
|
||||
// KDU core header files
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
#include "kdu_params.h"
|
||||
#include "kdu_compressed.h"
|
||||
#include "kdu_sample_processing.h"
|
||||
|
||||
#include "llkdumem.h"
|
||||
|
||||
#include "llblockdata.h"
|
||||
#include "llerror.h"
|
||||
|
||||
|
||||
BOOL LLBlockDecoder::decodeU32(LLBlockDataU32 &block_data, U8 *source_data, const U32 source_size) const
|
||||
{
|
||||
U32 width, height;
|
||||
|
||||
llassert(source_data);
|
||||
|
||||
LLKDUMemSource source(source_data, source_size);
|
||||
|
||||
source.reset();
|
||||
|
||||
kdu_codestream codestream;
|
||||
|
||||
codestream.create(&source);
|
||||
codestream.set_fast();
|
||||
|
||||
kdu_dims dims;
|
||||
codestream.get_dims(0,dims);
|
||||
llassert(codestream.get_num_components() == 1);
|
||||
|
||||
width = dims.size.x;
|
||||
height = dims.size.y;
|
||||
|
||||
// Assumes U32 data.
|
||||
U8 *output = block_data.getData();
|
||||
|
||||
kdu_dims tile_indices;
|
||||
codestream.get_valid_tiles(tile_indices);
|
||||
|
||||
kdu_coords tpos;
|
||||
tpos.x = 0;
|
||||
tpos.y = 0;
|
||||
|
||||
// Now we are ready to walk through the tiles processing them one-by-one.
|
||||
while (tpos.y < tile_indices.size.y)
|
||||
{
|
||||
while (tpos.x < tile_indices.size.x)
|
||||
{
|
||||
kdu_tile tile = codestream.open_tile(tpos+tile_indices.pos);
|
||||
|
||||
kdu_resolution res = tile.access_component(0).access_resolution();
|
||||
kdu_dims tile_dims;
|
||||
res.get_dims(tile_dims);
|
||||
kdu_coords offset = tile_dims.pos - dims.pos;
|
||||
int row_gap = block_data.getRowStride(); // inter-row separation
|
||||
kdu_byte *buf = output + offset.y*row_gap + offset.x*4;
|
||||
|
||||
kdu_tile_comp tile_comp = tile.access_component(0);
|
||||
bool reversible = tile_comp.get_reversible();
|
||||
U32 precision = tile_comp.get_bit_depth();
|
||||
U32 precision_scale = 1 << precision;
|
||||
llassert(precision >= 8); // Else would have used 16 bit representation
|
||||
|
||||
kdu_resolution comp_res = tile_comp.access_resolution(); // Get top resolution
|
||||
kdu_dims comp_dims;
|
||||
comp_res.get_dims(comp_dims);
|
||||
|
||||
bool use_shorts = (tile_comp.get_bit_depth(true) <= 16);
|
||||
|
||||
kdu_line_buf line;
|
||||
kdu_sample_allocator allocator;
|
||||
kdu_pull_ifc engine;
|
||||
|
||||
line.pre_create(&allocator, comp_dims.size.x, reversible, use_shorts);
|
||||
if (res.which() == 0) // No DWT levels used
|
||||
{
|
||||
engine = kdu_decoder(res.access_subband(LL_BAND), &allocator, use_shorts);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine = kdu_synthesis(res, &allocator, use_shorts);
|
||||
}
|
||||
allocator.finalize(); // Actually creates buffering resources
|
||||
|
||||
line.create(); // Grabs resources from the allocator.
|
||||
|
||||
// Do the actual processing
|
||||
while (tile_dims.size.y--)
|
||||
{
|
||||
engine.pull(line, true);
|
||||
int width = line.get_width();
|
||||
|
||||
llassert(line.get_buf32());
|
||||
llassert(!line.is_absolute());
|
||||
// Decompressed samples have a 32-bit representation (integer or float)
|
||||
kdu_sample32 *sp = line.get_buf32();
|
||||
// Transferring normalized floating point data.
|
||||
U32 *dest_u32 = (U32 *)buf;
|
||||
for (; width > 0; width--, sp++, dest_u32++)
|
||||
{
|
||||
if (sp->fval < -0.5f)
|
||||
{
|
||||
*dest_u32 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest_u32 = (U32)((sp->fval + 0.5f)*precision_scale);
|
||||
}
|
||||
}
|
||||
buf += row_gap;
|
||||
}
|
||||
engine.destroy();
|
||||
tile.close();
|
||||
tpos.x++;
|
||||
}
|
||||
tpos.y++;
|
||||
tpos.x = 0;
|
||||
}
|
||||
codestream.destroy();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLBlockDecoder::decodeF32(LLBlockDataF32 &block_data, U8 *source_data, const U32 source_size, const F32 min, const F32 max) const
|
||||
{
|
||||
U32 width, height;
|
||||
F32 range, range_inv, float_offset;
|
||||
bool use_shorts = false;
|
||||
|
||||
range = max - min;
|
||||
range_inv = 1.f / range;
|
||||
float_offset = 0.5f*(max + min);
|
||||
|
||||
llassert(source_data);
|
||||
|
||||
LLKDUMemSource source(source_data, source_size);
|
||||
|
||||
source.reset();
|
||||
|
||||
kdu_codestream codestream;
|
||||
|
||||
codestream.create(&source);
|
||||
codestream.set_fast();
|
||||
|
||||
kdu_dims dims;
|
||||
codestream.get_dims(0,dims);
|
||||
llassert(codestream.get_num_components() == 1);
|
||||
|
||||
width = dims.size.x;
|
||||
height = dims.size.y;
|
||||
|
||||
// Assumes F32 data.
|
||||
U8 *output = block_data.getData();
|
||||
|
||||
kdu_dims tile_indices;
|
||||
codestream.get_valid_tiles(tile_indices);
|
||||
|
||||
kdu_coords tpos;
|
||||
tpos.x = 0;
|
||||
tpos.y = 0;
|
||||
|
||||
// Now we are ready to walk through the tiles processing them one-by-one.
|
||||
while (tpos.y < tile_indices.size.y)
|
||||
{
|
||||
while (tpos.x < tile_indices.size.x)
|
||||
{
|
||||
kdu_tile tile = codestream.open_tile(tpos+tile_indices.pos);
|
||||
|
||||
kdu_resolution res = tile.access_component(0).access_resolution();
|
||||
kdu_dims tile_dims;
|
||||
res.get_dims(tile_dims);
|
||||
kdu_coords offset = tile_dims.pos - dims.pos;
|
||||
int row_gap = block_data.getRowStride(); // inter-row separation
|
||||
kdu_byte *buf = output + offset.y*row_gap + offset.x*4;
|
||||
|
||||
kdu_tile_comp tile_comp = tile.access_component(0);
|
||||
bool reversible = tile_comp.get_reversible();
|
||||
|
||||
kdu_resolution comp_res = tile_comp.access_resolution(); // Get top resolution
|
||||
kdu_dims comp_dims;
|
||||
comp_res.get_dims(comp_dims);
|
||||
|
||||
kdu_line_buf line;
|
||||
kdu_sample_allocator allocator;
|
||||
kdu_pull_ifc engine;
|
||||
|
||||
line.pre_create(&allocator, comp_dims.size.x, reversible, use_shorts);
|
||||
if (res.which() == 0) // No DWT levels used
|
||||
{
|
||||
engine = kdu_decoder(res.access_subband(LL_BAND), &allocator, use_shorts);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine = kdu_synthesis(res, &allocator, use_shorts);
|
||||
}
|
||||
allocator.finalize(); // Actually creates buffering resources
|
||||
|
||||
line.create(); // Grabs resources from the allocator.
|
||||
|
||||
// Do the actual processing
|
||||
while (tile_dims.size.y--)
|
||||
{
|
||||
engine.pull(line, true);
|
||||
int width = line.get_width();
|
||||
|
||||
llassert(line.get_buf32());
|
||||
llassert(!line.is_absolute());
|
||||
// Decompressed samples have a 32-bit representation (integer or float)
|
||||
kdu_sample32 *sp = line.get_buf32();
|
||||
// Transferring normalized floating point data.
|
||||
F32 *dest_f32 = (F32 *)buf;
|
||||
for (; width > 0; width--, sp++, dest_f32++)
|
||||
{
|
||||
if (sp->fval < -0.5f)
|
||||
{
|
||||
*dest_f32 = min;
|
||||
}
|
||||
else if (sp->fval > 0.5f)
|
||||
{
|
||||
*dest_f32 = max;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest_f32 = (sp->fval) * range + float_offset;
|
||||
}
|
||||
}
|
||||
buf += row_gap;
|
||||
}
|
||||
engine.destroy();
|
||||
tile.close();
|
||||
tpos.x++;
|
||||
}
|
||||
tpos.y++;
|
||||
tpos.x = 0;
|
||||
}
|
||||
codestream.destroy();
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @file llblockdecoder.h
|
||||
* @brief Image block decompression
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLBLOCKDECODER_H
|
||||
#define LL_LLBLOCKDECODER_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
class LLBlockDataU32;
|
||||
class LLBlockDataF32;
|
||||
|
||||
class LLBlockDecoder
|
||||
{
|
||||
public:
|
||||
BOOL decodeU32(LLBlockDataU32 &block_data, U8 *source_data, const U32 source_size) const;
|
||||
BOOL decodeF32(LLBlockDataF32 &block_data, U8 *source_data, const U32 source_size, const F32 min, const F32 max) const;
|
||||
};
|
||||
|
||||
#endif // LL_LLBLOCKDECODER_H
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
/**
|
||||
* @file llblockencoder.cpp
|
||||
* @brief Image block compression
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llblockencoder.h"
|
||||
|
||||
// KDU core header files
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
#include "kdu_params.h"
|
||||
#include "kdu_compressed.h"
|
||||
#include "kdu_sample_processing.h"
|
||||
|
||||
#include "llkdumem.h"
|
||||
|
||||
#include "llblockdata.h"
|
||||
#include "llerror.h"
|
||||
|
||||
LLBlockEncoder::LLBlockEncoder()
|
||||
{
|
||||
mBPP = 0.f;
|
||||
}
|
||||
|
||||
U8 *LLBlockEncoder::encode(const LLBlockData &block_data, U32 &output_size) const
|
||||
{
|
||||
switch (block_data.getType())
|
||||
{
|
||||
case LLBlockData::BLOCK_TYPE_U32:
|
||||
{
|
||||
LLBlockDataU32 &bd_u32 = (LLBlockDataU32 &)block_data;
|
||||
return encodeU32(bd_u32, output_size);
|
||||
}
|
||||
case LLBlockData::BLOCK_TYPE_F32:
|
||||
{
|
||||
LLBlockDataF32 &bd_f32 = (LLBlockDataF32 &)block_data;
|
||||
return encodeF32(bd_f32, output_size);
|
||||
}
|
||||
default:
|
||||
llerrs << "Unsupported block type!" << llendl;
|
||||
output_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
U8 *LLBlockEncoder::encodeU32(const LLBlockDataU32 &block_data, U32 &output_size) const
|
||||
{
|
||||
// OK, for now, just use the standard KDU encoder, with a single channel
|
||||
// integer channel.
|
||||
|
||||
// Collect simple arguments.
|
||||
bool allow_rate_prediction, allow_shorts, mem, quiet, no_weights;
|
||||
|
||||
allow_rate_prediction = true;
|
||||
allow_shorts = false;
|
||||
no_weights = false;
|
||||
bool use_absolute = false;
|
||||
mem = false;
|
||||
quiet = false;
|
||||
|
||||
// Set codestream options
|
||||
siz_params siz;
|
||||
S16 precision = block_data.getPrecision();
|
||||
|
||||
siz.set(Sdims,0,0,(U16)block_data.getHeight());
|
||||
siz.set(Sdims,0,1,(U16)block_data.getWidth());
|
||||
siz.set(Ssigned,0,0,false);
|
||||
siz.set(Scomponents,0,0,1);
|
||||
siz.set(Sprecision,0,0, precision);
|
||||
|
||||
// Construct the `kdu_codestream' object and parse all remaining arguments.
|
||||
output_size = block_data.getSize();
|
||||
if (output_size < 1000)
|
||||
{
|
||||
output_size = 1000;
|
||||
}
|
||||
|
||||
U8 *output_buffer = new U8[output_size];
|
||||
|
||||
LLKDUMemTarget output(output_buffer, output_size, block_data.getSize());
|
||||
|
||||
kdu_codestream codestream;
|
||||
codestream.create(&siz,&output);
|
||||
|
||||
codestream.access_siz()->parse_string("Clayers=1");
|
||||
codestream.access_siz()->finalize_all();
|
||||
|
||||
kdu_tile tile = codestream.open_tile(kdu_coords(0,0));
|
||||
|
||||
// Open tile-components and create processing engines and resources
|
||||
kdu_dims dims;
|
||||
kdu_sample_allocator allocator;
|
||||
kdu_tile_comp tile_comp;
|
||||
kdu_line_buf line;
|
||||
kdu_push_ifc engine;
|
||||
|
||||
tile_comp = tile.access_component(0);
|
||||
kdu_resolution res = tile_comp.access_resolution(); // Get top resolution
|
||||
|
||||
res.get_dims(dims);
|
||||
|
||||
line.pre_create(&allocator,dims.size.x, use_absolute, allow_shorts);
|
||||
|
||||
if (res.which() == 0) // No DWT levels (should not occur in this example)
|
||||
{
|
||||
engine = kdu_encoder(res.access_subband(LL_BAND),&allocator, use_absolute);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine = kdu_analysis(res,&allocator, use_absolute);
|
||||
}
|
||||
|
||||
allocator.finalize(); // Actually creates buffering resources
|
||||
line.create(); // Grabs resources from the allocator.
|
||||
|
||||
// Now walk through the lines of the buffer, pushing them into the
|
||||
// relevant tile-component processing engines.
|
||||
|
||||
U32 *source_u32 = NULL;
|
||||
F32 scale_inv = 1.f / (1 << precision);
|
||||
|
||||
S32 y;
|
||||
for (y = 0; y < dims.size.y; y++)
|
||||
{
|
||||
source_u32 = (U32*)(block_data.getData() + y * block_data.getRowStride());
|
||||
kdu_sample32 *dest = line.get_buf32();
|
||||
for (S32 n=dims.size.x; n > 0; n--, dest++, source_u32++)
|
||||
{
|
||||
// Just pack it in, for now.
|
||||
dest->fval = (F32)(*source_u32) * scale_inv - 0.5f;// - 0.5f;
|
||||
}
|
||||
engine.push(line, true);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
engine.destroy(); // engines are interfaces; no default destructors
|
||||
|
||||
// Produce the final compressed output.
|
||||
kdu_long layer_bytes[1] = {0};
|
||||
|
||||
layer_bytes[0] = (kdu_long) (mBPP*block_data.getWidth()*block_data.getHeight());
|
||||
// Here we are not requesting specific sizes for any of the 12
|
||||
// quality layers. As explained in the description of
|
||||
// "kdu_codestream::flush" (see "kdu_compressed.h"), the rate allocator
|
||||
// will then assign the layers in such a way as to achieve roughly
|
||||
// two quality layers per octave change in bit-rate, with the final
|
||||
// layer reaching true lossless quality.
|
||||
|
||||
codestream.flush(layer_bytes,1);
|
||||
// You can see how many bytes were assigned
|
||||
// to each quality layer by looking at the entries of `layer_bytes' here.
|
||||
// The flush function can do a lot of interesting things which you may
|
||||
// want to spend some time looking into. In addition to targeting
|
||||
// specific bit-rates for each quality layer, it can be configured to
|
||||
// use rate-distortion slope thresholds of your choosing and to return
|
||||
// the thresholds which it finds to be best for any particular set of
|
||||
// target layer sizes. This opens the door to feedback-oriented rate
|
||||
// control for video. You should also look into the
|
||||
// "kdu_codestream::set_max_bytes" and
|
||||
// "kdu_codestream::set_min_slope_threshold" functions which can be
|
||||
// used to significantly speed up compression.
|
||||
codestream.destroy(); // All done: simple as that.
|
||||
|
||||
// Now that we're done encoding, create the new data buffer for the compressed
|
||||
// image and stick it there.
|
||||
|
||||
U8 *output_data = new U8[output_size];
|
||||
|
||||
memcpy(output_data, output_buffer, output_size);
|
||||
|
||||
output.close(); // Not really necessary here.
|
||||
|
||||
return output_data;
|
||||
}
|
||||
|
||||
U8 *LLBlockEncoder::encodeF32(const LLBlockDataF32 &block_data, U32 &output_size) const
|
||||
{
|
||||
// OK, for now, just use the standard KDU encoder, with a single channel
|
||||
// integer channel.
|
||||
|
||||
// Collect simple arguments.
|
||||
bool allow_rate_prediction, allow_shorts, mem, quiet, no_weights;
|
||||
|
||||
allow_rate_prediction = true;
|
||||
allow_shorts = false;
|
||||
no_weights = false;
|
||||
bool use_absolute = false;
|
||||
mem = false;
|
||||
quiet = false;
|
||||
|
||||
F32 min, max, range, range_inv, offset;
|
||||
min = block_data.getMin();
|
||||
max = block_data.getMax();
|
||||
range = max - min;
|
||||
range_inv = 1.f / range;
|
||||
offset = 0.5f*(max + min);
|
||||
|
||||
// Set codestream options
|
||||
siz_params siz;
|
||||
S16 precision = block_data.getPrecision(); // Assume precision is always 32 bits for floating point.
|
||||
|
||||
siz.set(Sdims,0,0,(U16)block_data.getHeight());
|
||||
siz.set(Sdims,0,1,(U16)block_data.getWidth());
|
||||
siz.set(Ssigned,0,0,false);
|
||||
siz.set(Scomponents,0,0,1);
|
||||
siz.set(Sprecision,0,0, precision);
|
||||
|
||||
// Construct the `kdu_codestream' object and parse all remaining arguments.
|
||||
output_size = block_data.getSize();
|
||||
if (output_size < 1000)
|
||||
{
|
||||
output_size = 1000;
|
||||
}
|
||||
|
||||
U8 *output_buffer = new U8[output_size*2];
|
||||
|
||||
LLKDUMemTarget output(output_buffer, output_size, block_data.getSize());
|
||||
|
||||
kdu_codestream codestream;
|
||||
codestream.create(&siz,&output);
|
||||
|
||||
codestream.access_siz()->parse_string("Clayers=1");
|
||||
codestream.access_siz()->finalize_all();
|
||||
|
||||
kdu_tile tile = codestream.open_tile(kdu_coords(0,0));
|
||||
|
||||
// Open tile-components and create processing engines and resources
|
||||
kdu_dims dims;
|
||||
kdu_sample_allocator allocator;
|
||||
kdu_tile_comp tile_comp;
|
||||
kdu_line_buf line;
|
||||
kdu_push_ifc engine;
|
||||
|
||||
tile_comp = tile.access_component(0);
|
||||
kdu_resolution res = tile_comp.access_resolution(); // Get top resolution
|
||||
|
||||
res.get_dims(dims);
|
||||
|
||||
line.pre_create(&allocator,dims.size.x, use_absolute, allow_shorts);
|
||||
|
||||
if (res.which() == 0) // No DWT levels (should not occur in this example)
|
||||
{
|
||||
engine = kdu_encoder(res.access_subband(LL_BAND),&allocator, use_absolute);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine = kdu_analysis(res,&allocator, use_absolute);
|
||||
}
|
||||
|
||||
allocator.finalize(); // Actually creates buffering resources
|
||||
line.create(); // Grabs resources from the allocator.
|
||||
|
||||
// Now walk through the lines of the buffer, pushing them into the
|
||||
// relevant tile-component processing engines.
|
||||
|
||||
F32 *source_f32 = NULL;
|
||||
|
||||
S32 y;
|
||||
for (y = 0; y < dims.size.y; y++)
|
||||
{
|
||||
source_f32 = (F32*)(block_data.getData() + y * block_data.getRowStride());
|
||||
kdu_sample32 *dest = line.get_buf32();
|
||||
for (S32 n=dims.size.x; n > 0; n--, dest++, source_f32++)
|
||||
{
|
||||
dest->fval = ((*source_f32) - offset) * range_inv;
|
||||
}
|
||||
engine.push(line, true);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
engine.destroy(); // engines are interfaces; no default destructors
|
||||
|
||||
// Produce the final compressed output.
|
||||
kdu_long layer_bytes[1] = {0};
|
||||
|
||||
layer_bytes[0] = (kdu_long) (mBPP*block_data.getWidth()*block_data.getHeight());
|
||||
// Here we are not requesting specific sizes for any of the 12
|
||||
// quality layers. As explained in the description of
|
||||
// "kdu_codestream::flush" (see "kdu_compressed.h"), the rate allocator
|
||||
// will then assign the layers in such a way as to achieve roughly
|
||||
// two quality layers per octave change in bit-rate, with the final
|
||||
// layer reaching true lossless quality.
|
||||
|
||||
codestream.flush(layer_bytes,1);
|
||||
// You can see how many bytes were assigned
|
||||
// to each quality layer by looking at the entries of `layer_bytes' here.
|
||||
// The flush function can do a lot of interesting things which you may
|
||||
// want to spend some time looking into. In addition to targeting
|
||||
// specific bit-rates for each quality layer, it can be configured to
|
||||
// use rate-distortion slope thresholds of your choosing and to return
|
||||
// the thresholds which it finds to be best for any particular set of
|
||||
// target layer sizes. This opens the door to feedback-oriented rate
|
||||
// control for video. You should also look into the
|
||||
// "kdu_codestream::set_max_bytes" and
|
||||
// "kdu_codestream::set_min_slope_threshold" functions which can be
|
||||
// used to significantly speed up compression.
|
||||
codestream.destroy(); // All done: simple as that.
|
||||
|
||||
// Now that we're done encoding, create the new data buffer for the compressed
|
||||
// image and stick it there.
|
||||
|
||||
U8 *output_data = new U8[output_size];
|
||||
|
||||
memcpy(output_data, output_buffer, output_size);
|
||||
|
||||
output.close(); // Not really necessary here.
|
||||
|
||||
delete[] output_buffer;
|
||||
|
||||
return output_data;
|
||||
}
|
||||
|
||||
|
||||
void LLBlockEncoder::setBPP(const F32 bpp)
|
||||
{
|
||||
mBPP = bpp;
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/**
|
||||
* @file llblockencoder.h
|
||||
* @brief Image block compression
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLBLOCKENCODER_H
|
||||
#define LL_LLBLOCKENCODER_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
|
||||
class LLBlockData;
|
||||
class LLBlockDataU32;
|
||||
class LLBlockDataF32;
|
||||
|
||||
class LLBlockEncoder
|
||||
{
|
||||
F32 mBPP; // bits per point
|
||||
public:
|
||||
LLBlockEncoder();
|
||||
U8 *encode(const LLBlockData &block_data, U32 &output_size) const;
|
||||
U8 *encodeU32(const LLBlockDataU32 &block_data, U32 &output_size) const;
|
||||
U8 *encodeF32(const LLBlockDataF32 &block_data, U32 &output_size) const;
|
||||
|
||||
void setBPP(const F32 bpp);
|
||||
};
|
||||
|
||||
#endif // LL_LLBLOCKENCODER_H
|
||||
|
||||
Loading…
Reference in New Issue