Add load_sub_image

This commit is contained in:
rdb 2014-09-13 19:49:17 +00:00
parent 02e95bdba3
commit 340169c80c
3 changed files with 91 additions and 18 deletions

View File

@ -351,6 +351,23 @@ load(const PfmFile &pfm, int z, int n, const LoaderOptions &options) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::load_sub_image
// Access: Published
// Description: Stores the indicated image in a region of the
// texture. The texture properties remain unchanged.
// This can be more efficient than updating an entire
// texture, but has a few restrictions: for one, you
// must ensure that the texture is still in RAM (eg.
// using set_keep_ram_image) and it may not be
// compressed.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
load_sub_image(const PNMImage &image, int x, int y, int z, int n) {
CDWriter cdata(_cycler, true);
return do_load_sub_image(cdata, image, x, y, z, n);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::store
// Access: Published

View File

@ -1332,7 +1332,7 @@ generate_simple_ram_image() {
size_t expected_page_size = (size_t)(x_size * y_size * 4);
PTA_uchar image = PTA_uchar::empty_array(expected_page_size, get_class_type());
convert_from_pnmimage(image, expected_page_size, 0, scaled, 4, 1);
convert_from_pnmimage(image, expected_page_size, x_size, 0, 0, 0, scaled, 4, 1);
do_set_simple_ram_image(cdata, image, x_size, y_size);
cdata->_simple_image_date_generated = (PN_int32)time(NULL);
@ -3368,7 +3368,7 @@ do_read_one(CData *cdata, const Filename &fullpath, const Filename &alpha_fullpa
image.take_from(new_image);
}
}
if (!do_load_one(cdata, image, fullpath.get_basename(), z, n, options)) {
return false;
}
@ -3438,14 +3438,16 @@ do_load_one(CData *cdata, const PNMImage &pnmimage, const string &name, int z, i
Thread::consider_yield();
convert_from_pnmimage(cdata->_ram_images[n]._image,
do_get_expected_ram_mipmap_page_size(cdata, n), z,
scaled, cdata->_num_components, cdata->_component_width);
do_get_expected_ram_mipmap_page_size(cdata, n),
x_size, 0, 0, z, scaled,
cdata->_num_components, cdata->_component_width);
} else {
// Now copy the pixel data from the PNMImage into our internal
// cdata->_image component.
convert_from_pnmimage(cdata->_ram_images[n]._image,
do_get_expected_ram_mipmap_page_size(cdata, n), z,
pnmimage, cdata->_num_components, cdata->_component_width);
do_get_expected_ram_mipmap_page_size(cdata, n),
x_size, 0, 0, z, pnmimage,
cdata->_num_components, cdata->_component_width);
}
Thread::consider_yield();
@ -3520,6 +3522,40 @@ do_load_one(CData *cdata, const PfmFile &pfm, const string &name, int z, int n,
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::do_load_sub_image
// Access: Protected, Virtual
// Description: Internal method to load an image into a section of
// a texture page or mipmap level.
////////////////////////////////////////////////////////////////////
bool Texture::
do_load_sub_image(CData *cdata, const PNMImage &image, int x, int y, int z, int n) {
nassertr(n >= 0 && n < cdata->_ram_images.size(), false);
int tex_x_size = do_get_expected_mipmap_x_size(cdata, n);
int tex_y_size = do_get_expected_mipmap_y_size(cdata, n);
int tex_z_size = do_get_expected_mipmap_z_size(cdata, n);
nassertr(x >= 0 && x < tex_x_size, false);
nassertr(y >= 0 && y < tex_y_size, false);
nassertr(z >= 0 && z < tex_z_size, false);
nassertr(image.get_x_size() + x < tex_x_size, false);
nassertr(image.get_y_size() + y < tex_y_size, false);
// Flip y
y = cdata->_y_size - (image.get_y_size() + y);
cdata->inc_image_modified();
do_modify_ram_mipmap_image(cdata, n);
convert_from_pnmimage(cdata->_ram_images[n]._image,
do_get_expected_ram_mipmap_page_size(cdata, n),
tex_x_size, x, y, z, image,
cdata->_num_components, cdata->_component_width);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::do_read_txo_file
// Access: Protected
@ -6009,12 +6045,22 @@ do_get_bam_rawdata(CData *cdata) {
// indicated PNMImage into the given ram_image.
////////////////////////////////////////////////////////////////////
void Texture::
convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
const PNMImage &pnmimage,
int num_components, int component_width) {
convert_from_pnmimage(PTA_uchar &image, size_t page_size,
int row_stride, int x, int y, int z,
const PNMImage &pnmimage, int num_components,
int component_width) {
int x_size = pnmimage.get_x_size();
int y_size = pnmimage.get_y_size();
xelval maxval = pnmimage.get_maxval();
int pixel_size = num_components * component_width;
int row_skip = 0;
if (row_stride == 0) {
row_stride = x_size;
} else {
row_skip = (row_stride - x_size) * pixel_size;
nassertv(row_skip >= 0);
}
bool is_grayscale = (num_components == 1 || num_components == 2);
bool has_alpha = (num_components == 2 || num_components == 4);
@ -6024,6 +6070,10 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
nassertv(idx + page_size <= image.size());
unsigned char *p = &image[idx];
if (x != 0 || y != 0) {
p += (row_stride * y + x) * pixel_size;
}
if (maxval == 255 && component_width == 1) {
// Most common case: one byte per pixel, and the source image
// shows a maxval of 255. No scaling is necessary.
@ -6044,6 +6094,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
}
}
}
p += row_skip;
}
} else if (maxval == 65535 && component_width == 2) {
@ -6052,7 +6103,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
for (int j = y_size-1; j >= 0; j--) {
for (int i = 0; i < x_size; i++) {
if (is_grayscale) {
store_unscaled_short(p, pnmimage.get_gray_val(i, j));
store_unscaled_short(p, pnmimage.get_gray_val(i, j));
} else {
store_unscaled_short(p, pnmimage.get_blue_val(i, j));
store_unscaled_short(p, pnmimage.get_green_val(i, j));
@ -6066,6 +6117,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
}
}
}
p += row_skip;
}
} else if (component_width == 1) {
@ -6091,6 +6143,7 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
}
}
}
p += row_skip;
}
} else { // component_width == 2
@ -6116,10 +6169,9 @@ convert_from_pnmimage(PTA_uchar &image, size_t page_size, int z,
}
}
}
p += row_skip;
}
}
nassertv(p == &image[idx] + page_size);
}
////////////////////////////////////////////////////////////////////

View File

@ -279,6 +279,7 @@ PUBLISHED:
BLOCKING INLINE bool load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options = LoaderOptions());
BLOCKING INLINE bool load(const PfmFile &pfm, const LoaderOptions &options = LoaderOptions());
BLOCKING INLINE bool load(const PfmFile &pfm, int z, int n, const LoaderOptions &options = LoaderOptions());
BLOCKING INLINE bool load_sub_image(const PNMImage &pnmimage, int x, int y, int z=0, int n=0);
BLOCKING INLINE bool store(PNMImage &pnmimage) const;
BLOCKING INLINE bool store(PNMImage &pnmimage, int z, int n) const;
BLOCKING INLINE bool store(PfmFile &pfm) const;
@ -569,6 +570,8 @@ protected:
virtual bool do_load_one(CData *cdata,
const PfmFile &pfm, const string &name,
int z, int n, const LoaderOptions &options);
virtual bool do_load_sub_image(CData *cdata, const PNMImage &image,
int x, int y, int z, int n);
bool do_read_txo_file(CData *cdata, const Filename &fullpath);
bool do_read_txo(CData *cdata, istream &in, const string &filename);
bool do_read_dds_file(CData *cdata, const Filename &fullpath, bool header_only);
@ -682,19 +685,20 @@ protected:
};
private:
static void convert_from_pnmimage(PTA_uchar &image, size_t page_size,
int z, const PNMImage &pnmimage,
static void convert_from_pnmimage(PTA_uchar &image, size_t page_size,
int row_stride, int x, int y, int z,
const PNMImage &pnmimage,
int num_components, int component_width);
static void convert_from_pfm(PTA_uchar &image, size_t page_size,
int z, const PfmFile &pfm,
static void convert_from_pfm(PTA_uchar &image, size_t page_size,
int z, const PfmFile &pfm,
int num_components, int component_width);
static bool convert_to_pnmimage(PNMImage &pnmimage, int x_size, int y_size,
int num_components, int component_width,
CPTA_uchar image, size_t page_size,
CPTA_uchar image, size_t page_size,
int z);
static bool convert_to_pfm(PfmFile &pfm, int x_size, int y_size,
int num_components, int component_width,
CPTA_uchar image, size_t page_size,
CPTA_uchar image, size_t page_size,
int z);
static PTA_uchar read_dds_level_bgr8(Texture *tex, CData *cdata, const DDSHeader &header,
int n, istream &in);