本文整理汇总了C++中ImageBuf类的典型用法代码示例。如果您正苦于以下问题:C++ ImageBuf类的具体用法?C++ ImageBuf怎么用?C++ ImageBuf使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ImageBuf类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: string
std::string
ImageBufAlgo::computePixelHashSHA1 (const ImageBuf &src,
const std::string & extrainfo,
ROI roi, int blocksize, int nthreads)
{
if (! roi.defined())
roi = get_roi (src.spec());
// Fall back to whole-image hash for only one block
if (blocksize <= 0 || blocksize >= roi.height())
return simplePixelHashSHA1 (src, extrainfo, roi);
// Request for 0 threads means "use the OIIO global thread count"
if (nthreads <= 0)
OIIO::getattribute ("threads", nthreads);
int nblocks = (roi.height()+blocksize-1) / blocksize;
std::vector<std::string> results (nblocks);
if (nthreads <= 1) {
sha1_hasher (&src, roi, blocksize, &results[0], 0);
} else {
// parallel case
boost::thread_group threads;
int blocks_per_thread = (nblocks+nthreads-1) / nthreads;
ROI broi = roi;
for (int b = 0, t = 0; b < nblocks; b += blocks_per_thread, ++t) {
int y = roi.ybegin + b*blocksize;
if (y >= roi.yend)
break;
broi.ybegin = y;
broi.yend = std::min (y+blocksize*blocks_per_thread, roi.yend);
threads.add_thread (new boost::thread (sha1_hasher, &src, broi,
blocksize, &results[0], b));
}
threads.join_all ();
}
#ifdef USE_OPENSSL
// If OpenSSL was available at build time, use its SHA-1
// implementation, which is about 20% faster than CSHA1.
SHA_CTX sha;
SHA1_Init (&sha);
for (int b = 0; b < nblocks; ++b)
SHA1_Update (&sha, results[b].c_str(), results[b].size());
if (extrainfo.size())
SHA1_Update (&sha, extrainfo.c_str(), extrainfo.size());
unsigned char md[SHA_DIGEST_LENGTH];
char hash_digest[2*SHA_DIGEST_LENGTH+1];
SHA1_Final (md, &sha);
for (int i = 0; i < SHA_DIGEST_LENGTH; ++i)
sprintf (hash_digest+2*i, "%02X", (int)md[i]);
hash_digest[2*SHA_DIGEST_LENGTH] = 0;
return std::string (hash_digest);
#else
// Fall back on CSHA1 if OpenSSL was not available or if
CSHA1 sha;
sha.Reset ();
for (int b = 0; b < nblocks; ++b)
sha.Update ((const unsigned char *)results[b].c_str(), results[b].size());
if (extrainfo.size())
sha.Update ((const unsigned char *)extrainfo.c_str(), extrainfo.size());
sha.Final ();
std::string hash_digest;
sha.ReportHashStl (hash_digest, CSHA1::REPORT_HEX_SHORT);
return hash_digest;
#endif
}
示例2:
bool
ImageBufAlgo::histogram (const ImageBuf &A, int channel,
std::vector<imagesize_t> &histogram, int bins,
float min, float max, imagesize_t *submin,
imagesize_t *supermax, ROI roi)
{
if (A.spec().format != TypeDesc::TypeFloat) {
A.error ("Unsupported pixel data format '%s'", A.spec().format);
return false;
}
if (A.nchannels() == 0) {
A.error ("Input image must have at least 1 channel");
return false;
}
if (channel < 0 || channel >= A.nchannels()) {
A.error ("Invalid channel %d for input image with channels 0 to %d",
channel, A.nchannels()-1);
return false;
}
if (bins < 1) {
A.error ("The number of bins must be at least 1");
return false;
}
if (max <= min) {
A.error ("Invalid range, min must be strictly smaller than max");
return false;
}
// Specified ROI -> use it. Unspecified ROI -> initialize from A.
if (! roi.defined())
roi = get_roi (A.spec());
histogram_impl<float> (A, channel, histogram, bins, min, max,
submin, supermax, roi);
return ! A.has_error();
}
示例3: print_stats
static void
print_stats (const std::string &filename,
const ImageSpec &originalspec,
int subimage=0, int miplevel=0, bool indentmip=false)
{
const char *indent = indentmip ? " " : " ";
ImageBuf input;
if (! read_input (filename, input, subimage, miplevel)) {
std::cerr << "Stats: read error: " << input.geterror() << "\n";
return;
}
PixelStats stats;
if (! computePixelStats (stats, input)) {
printf ("%sStats: (unable to compute)\n", indent);
return;
}
// The original spec is used, otherwise the bit depth will
// be reported incorrectly (as FLOAT)
unsigned int maxval = get_intsample_maxval (originalspec);
printf ("%sStats Min: ", indent);
for (unsigned int i=0; i<stats.min.size(); ++i) {
print_stats_num (stats.min[i], maxval, true);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats Max: ", indent);
for (unsigned int i=0; i<stats.max.size(); ++i) {
print_stats_num (stats.max[i], maxval, true);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats Avg: ", indent);
for (unsigned int i=0; i<stats.avg.size(); ++i) {
print_stats_num (stats.avg[i], maxval, false);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats StdDev: ", indent);
for (unsigned int i=0; i<stats.stddev.size(); ++i) {
print_stats_num (stats.stddev[i], maxval, false);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats NanCount: ", indent);
for (unsigned int i=0; i<stats.nancount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.nancount[i]);
}
printf ("\n");
printf ("%sStats InfCount: ", indent);
for (unsigned int i=0; i<stats.infcount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.infcount[i]);
}
printf ("\n");
printf ("%sStats FiniteCount: ", indent);
for (unsigned int i=0; i<stats.finitecount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.finitecount[i]);
}
printf ("\n");
std::vector<float> constantValues(input.spec().nchannels);
if(isConstantColor(input, &constantValues[0])) {
printf ("%sConstant: Yes\n", indent);
printf ("%sConstant Color: ", indent);
for (unsigned int i=0; i<constantValues.size(); ++i) {
print_stats_num (constantValues[i], maxval, false);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
}
else {
printf ("%sConstant: No\n", indent);
}
if(isMonochrome(input)) {
printf ("%sMonochrome: Yes\n", indent);
} else {
printf ("%sMonochrome: No\n", indent);
}
}
示例4: test_zero_fill
// Test ImageBuf::zero and ImageBuf::fill
void test_zero_fill ()
{
const int WIDTH = 8;
const int HEIGHT = 6;
const int CHANNELS = 4;
ImageSpec spec (WIDTH, HEIGHT, CHANNELS, TypeDesc::FLOAT);
spec.alpha_channel = 3;
// Create a buffer -- pixels should be undefined
ImageBuf A ("A", spec);
// Set a pixel to an odd value, make sure it takes
const float arbitrary1[CHANNELS] = { 0.2, 0.3, 0.4, 0.5 };
A.setpixel (1, 1, arbitrary1);
float pixel[CHANNELS]; // test pixel
A.getpixel (1, 1, pixel);
for (int c = 0; c < CHANNELS; ++c)
OIIO_CHECK_EQUAL (pixel[c], arbitrary1[c]);
// Zero out and test that it worked
ImageBufAlgo::zero (A);
for (int j = 0; j < HEIGHT; ++j) {
for (int i = 0; i < WIDTH; ++i) {
float pixel[CHANNELS];
A.getpixel (i, j, pixel);
for (int c = 0; c < CHANNELS; ++c)
OIIO_CHECK_EQUAL (pixel[c], 0.0f);
}
}
// Test fill of whole image
const float arbitrary2[CHANNELS] = { 0.6, 0.7, 0.3, 0.9 };
ImageBufAlgo::fill (A, arbitrary2);
for (int j = 0; j < HEIGHT; ++j) {
for (int i = 0; i < WIDTH; ++i) {
float pixel[CHANNELS];
A.getpixel (i, j, pixel);
for (int c = 0; c < CHANNELS; ++c)
OIIO_CHECK_EQUAL (pixel[c], arbitrary2[c]);
}
}
// Test fill of partial image
const float arbitrary3[CHANNELS] = { 0.42, 0.43, 0.44, 0.45 };
{
const int xbegin = 3, xend = 5, ybegin = 0, yend = 4;
ImageBufAlgo::fill (A, arbitrary3, ROI(xbegin, xend, ybegin, yend));
for (int j = 0; j < HEIGHT; ++j) {
for (int i = 0; i < WIDTH; ++i) {
float pixel[CHANNELS];
A.getpixel (i, j, pixel);
if (j >= ybegin && j < yend && i >= xbegin && i < xend) {
for (int c = 0; c < CHANNELS; ++c)
OIIO_CHECK_EQUAL (pixel[c], arbitrary3[c]);
} else {
for (int c = 0; c < CHANNELS; ++c)
OIIO_CHECK_EQUAL (pixel[c], arbitrary2[c]);
}
}
}
}
}
示例5: scanline
bool
ImageBufAlgo::colorconvert (ImageBuf &dst, const ImageBuf &src,
const ColorProcessor* processor,
bool unpremult)
{
// If the processor is NULL, return false (error)
if (!processor)
return false;
ImageSpec dstspec = dst.spec();
std::vector<float> scanline(dstspec.width*4, 0.0f);
// Only process up to, and including, the first 4 channels.
// This does let us process images with fewer than 4 channels, which is the intent
// FIXME: Instead of loading the first 4 channels, obey dstspec.alpha_channel index
// (but first validate that the index is set properly for normal formats)
int channelsToCopy = std::min (4, dstspec.nchannels);
// Walk through all data in our buffer. (i.e., crop or overscan)
// FIXME: What about the display window? Should this actually promote
// the datawindow to be union of data + display? This is useful if
// the color of black moves. (In which case non-zero sections should
// now be promoted). Consider the lin->log of a roto element, where
// black now moves to non-black
//
// FIXME: Use the ImageBuf::ConstIterator<T,T> s (src); s.isValid()
// idiom for traversal instead, to allow for more efficient tile access
// iteration order
float * dstPtr = NULL;
const float fltmin = std::numeric_limits<float>::min();
for (int k = dstspec.z; k < dstspec.z+dstspec.depth; k++) {
for (int j = dstspec.y; j < dstspec.y+dstspec.height; j++) {
// Load the scanline
dstPtr = &scanline[0];
for (int i = dstspec.x; i < dstspec.x+dstspec.width ; i++) {
src.getpixel (i, j, dstPtr, channelsToCopy);
dstPtr += 4;
}
// Optionally unpremult
if ((channelsToCopy>=4) && unpremult) {
float alpha = 0.0;
for (int i=0; i<dstspec.width; ++i) {
alpha = scanline[4*i+3];
if (alpha > fltmin) {
scanline[4*i+0] /= alpha;
scanline[4*i+1] /= alpha;
scanline[4*i+2] /= alpha;
}
}
}
// Apply the color transformation in place
// This is always an rgba float image, due to the conversion above.
for(int i=0; i<dstspec.width; ++i)
{
scanline[4*i+0] = (*processor->t2)((*processor->t1)(scanline[4*i+0]));
scanline[4*i+1] = (*processor->t2)((*processor->t1)(scanline[4*i+1]));
scanline[4*i+2] = (*processor->t2)((*processor->t1)(scanline[4*i+2]));
}
// Optionally premult
if ((channelsToCopy>=4) && unpremult) {
float alpha = 0.0;
for (int i=0; i<dstspec.width; ++i) {
alpha = scanline[4*i+3];
if (alpha > fltmin) {
scanline[4*i+0] *= alpha;
scanline[4*i+1] *= alpha;
scanline[4*i+2] *= alpha;
}
}
}
// Store the scanline
dstPtr = &scanline[0];
for (int i = dstspec.x; i < dstspec.x+dstspec.width ; i++) {
dst.setpixel (i, j, dstPtr, channelsToCopy);
dstPtr += 4;
}
}
}
return true;
}
示例6: print_stats
static void
print_stats (const std::string &filename,
const ImageSpec &originalspec,
int subimage=0, int miplevel=0, bool indentmip=false)
{
PixelStats stats;
const char *indent = indentmip ? " " : " ";
ImageBuf input;
if (! read_input (filename, input, subimage, miplevel)) {
std::cerr << "Stats: read error: " << input.geterror() << "\n";
return;
}
if (! computePixelStats (stats, input)) {
printf ("%sStats: (unable to compute)\n", indent);
if (input.has_error())
std::cerr << "Error: " << input.geterror() << "\n";
return;
}
// The original spec is used, otherwise the bit depth will
// be reported incorrectly (as FLOAT)
unsigned int maxval = (unsigned int)get_intsample_maxval (originalspec);
printf ("%sStats Min: ", indent);
for (unsigned int i=0; i<stats.min.size(); ++i) {
print_stats_num (stats.min[i], maxval, true);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats Max: ", indent);
for (unsigned int i=0; i<stats.max.size(); ++i) {
print_stats_num (stats.max[i], maxval, true);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats Avg: ", indent);
for (unsigned int i=0; i<stats.avg.size(); ++i) {
print_stats_num (stats.avg[i], maxval, false);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats StdDev: ", indent);
for (unsigned int i=0; i<stats.stddev.size(); ++i) {
print_stats_num (stats.stddev[i], maxval, false);
printf (" ");
}
print_stats_footer (maxval);
printf ("\n");
printf ("%sStats NanCount: ", indent);
for (unsigned int i=0; i<stats.nancount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.nancount[i]);
}
printf ("\n");
printf ("%sStats InfCount: ", indent);
for (unsigned int i=0; i<stats.infcount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.infcount[i]);
}
printf ("\n");
printf ("%sStats FiniteCount: ", indent);
for (unsigned int i=0; i<stats.finitecount.size(); ++i) {
printf ("%llu ", (unsigned long long)stats.finitecount[i]);
}
printf ("\n");
if (input.deep()) {
const DeepData *dd (input.deepdata());
size_t npixels = dd->pixels();
size_t totalsamples = 0, emptypixels = 0;
size_t maxsamples = 0, minsamples = std::numeric_limits<size_t>::max();
for (size_t p = 0; p < npixels; ++p) {
size_t c = dd->samples(p);
totalsamples += c;
if (c > maxsamples)
maxsamples = c;
if (c < minsamples)
minsamples = c;
if (c == 0)
++emptypixels;
}
printf ("%sMin deep samples in any pixel : %llu\n", indent, (unsigned long long)minsamples);
printf ("%sMax deep samples in any pixel : %llu\n", indent, (unsigned long long)maxsamples);
printf ("%sAverage deep samples per pixel: %.2f\n", indent, double(totalsamples)/double(npixels));
printf ("%sTotal deep samples in all pixels: %llu\n", indent, (unsigned long long)totalsamples);
printf ("%sPixels with deep samples : %llu\n", indent, (unsigned long long)(npixels-emptypixels));
printf ("%sPixels with no deep samples: %llu\n", indent, (unsigned long long)emptypixels);
} else {
std::vector<float> constantValues(input.spec().nchannels);
if (isConstantColor(input, &constantValues[0])) {
printf ("%sConstant: Yes\n", indent);
//.........这里部分代码省略.........
示例7: flatten_
static bool
flatten_ (ImageBuf &dst, const ImageBuf &src,
ROI roi, int nthreads)
{
if (nthreads != 1 && roi.npixels() >= 1000) {
// Possible multiple thread case -- recurse via parallel_image
ImageBufAlgo::parallel_image (
boost::bind(flatten_<DSTTYPE>, boost::ref(dst), boost::cref(src),
_1 /*roi*/, 1 /*nthreads*/),
roi, nthreads);
return true;
}
const ImageSpec &srcspec (src.spec());
int nc = srcspec.nchannels;
int alpha_channel, RA_channel, GA_channel, BA_channel;
int R_channel, G_channel, B_channel;
int Z_channel, Zback_channel;
if (! find_deep_channels (srcspec, alpha_channel,
RA_channel, GA_channel, BA_channel,
R_channel, G_channel, B_channel,
Z_channel, Zback_channel)) {
dst.error ("No alpha channel could be identified");
return false;
}
ASSERT (alpha_channel >= 0 ||
(RA_channel >= 0 && GA_channel >= 0 && BA_channel >= 0));
float *val = ALLOCA (float, nc);
float &RAval (RA_channel >= 0 ? val[RA_channel] : val[alpha_channel]);
float &GAval (GA_channel >= 0 ? val[GA_channel] : val[alpha_channel]);
float &BAval (BA_channel >= 0 ? val[BA_channel] : val[alpha_channel]);
for (ImageBuf::Iterator<DSTTYPE> r (dst, roi); !r.done(); ++r) {
int x = r.x(), y = r.y(), z = r.z();
int samps = src.deep_samples (x, y, z);
// Clear accumulated values for this pixel (0 for colors, big for Z)
memset (val, 0, nc*sizeof(float));
if (Z_channel >= 0 && samps == 0)
val[Z_channel] = 1.0e30;
if (Zback_channel >= 0 && samps == 0)
val[Zback_channel] = 1.0e30;
for (int s = 0; s < samps; ++s) {
float RA = RAval, GA = GAval, BA = BAval; // make copies
float alpha = (RA + GA + BA) / 3.0f;
if (alpha >= 1.0f)
break;
for (int c = 0; c < nc; ++c) {
float v = src.deep_value (x, y, z, c, s);
if (c == Z_channel || c == Zback_channel)
val[c] *= alpha; // because Z are not premultiplied
float a;
if (c == R_channel)
a = RA;
else if (c == G_channel)
a = GA;
else if (c == B_channel)
a = BA;
else
a = alpha;
val[c] += (1.0f - a) * v;
}
}
for (int c = roi.chbegin; c < roi.chend; ++c)
r[c] = val[c];
}
return true;
}
示例8: go_bandit
#include "image.h"
using namespace std;
using namespace bandit;
using namespace Splash;
go_bandit([]() {
/*********/
describe("Image class", [&]() {
Image image;
before_each([&]() {
image = Image();
});
it("should get the same image specs", [&]() {
ImageBuf srcImg = image.get();
auto obj = image.serialize();
image.deserialize(obj);
ImageBuf dstImg = image.get();
ImageSpec src = srcImg.spec();
ImageSpec dst = dstImg.spec();
bool isIdentical = true;
if (src.width != dst.width)
isIdentical = false;
if (src.height != dst.height)
isIdentical = false;
if (src.channels != dst.channels)
isIdentical = false;
if (src.format != dst.format)
isIdentical = false;
示例9: if
bool
ImageBufAlgo::deepen (ImageBuf &dst, const ImageBuf &src, float zvalue,
ROI roi, int nthreads)
{
if (src.deep()) {
// For some reason, we were asked to deepen an already-deep image.
// So just copy it.
return dst.copy (src);
// FIXME: once paste works for deep files, this should really be
// return paste (dst, roi.xbegin, roi.ybegin, roi.zbegin, roi.chbegin,
// src, roi, nthreads);
}
// Construct an ideal spec for dst, which is like src but deep.
const ImageSpec &srcspec (src.spec());
int nc = srcspec.nchannels;
int zback_channel = -1;
ImageSpec force_spec = srcspec;
force_spec.deep = true;
force_spec.set_format (TypeDesc::FLOAT);
force_spec.channelformats.clear();
for (int c = 0; c < nc; ++c) {
if (force_spec.channelnames[c] == "Z")
force_spec.z_channel = c;
else if (force_spec.channelnames[c] == "Zback")
zback_channel = c;
}
bool add_z_channel = (force_spec.z_channel < 0);
if (add_z_channel) {
// No z channel? Make one.
force_spec.z_channel = force_spec.nchannels++;
force_spec.channelnames.push_back ("Z");
}
if (! IBAprep (roi, &dst, &src, NULL, &force_spec, IBAprep_SUPPORT_DEEP))
return false;
if (! dst.deep()) {
dst.error ("Cannot deepen to a flat image");
return false;
}
float *pixel = OIIO_ALLOCA (float, nc);
// First, figure out which pixels get a sample and which do not
for (int z = roi.zbegin; z < roi.zend; ++z)
for (int y = roi.ybegin; y < roi.yend; ++y)
for (int x = roi.xbegin; x < roi.xend; ++x) {
bool has_sample = false;
src.getpixel (x, y, z, pixel);
for (int c = 0; c < nc; ++c)
if (c != force_spec.z_channel && c != zback_channel
&& pixel[c] != 0.0f) {
has_sample = true;
break;
}
if (! has_sample && ! add_z_channel)
for (int c = 0; c < nc; ++c)
if ((c == force_spec.z_channel || c == zback_channel)
&& (pixel[c] != 0.0f && pixel[c] < 1e30)) {
has_sample = true;
break;
}
if (has_sample)
dst.set_deep_samples (x, y, z, 1);
}
dst.deep_alloc ();
// Now actually set the values
for (int z = roi.zbegin; z < roi.zend; ++z)
for (int y = roi.ybegin; y < roi.yend; ++y)
for (int x = roi.xbegin; x < roi.xend; ++x) {
if (dst.deep_samples (x, y, z) == 0)
continue;
for (int c = 0; c < nc; ++c)
dst.set_deep_value (x, y, z, c, 0 /*sample*/,
src.getchannel (x, y, z, c));
if (add_z_channel)
dst.set_deep_value (x, y, z, nc, 0, zvalue);
}
bool ok = true;
// FIXME -- the above doesn't split into threads. Someday, it should
// be refactored like this:
// OIIO_DISPATCH_COMMON_TYPES2 (ok, "deepen", deepen_,
// dst.spec().format, srcspec.format,
// dst, src, add_z_channel, z, roi, nthreads);
return ok;
}
示例10: main
int
main (int argc, char *argv[])
{
getargs (argc, argv);
std::cout << "Comparing \"" << filenames[0]
<< "\" and \"" << filenames[1] << "\"\n";
// Create a private ImageCache so we can customize its cache size
// and instruct it store everything internally as floats.
ImageCache *imagecache = ImageCache::create (true);
imagecache->attribute ("forcefloat", 1);
if (sizeof(void *) == 4) // 32 bit or 64?
imagecache->attribute ("max_memory_MB", 512.0);
else
imagecache->attribute ("max_memory_MB", 2048.0);
imagecache->attribute ("autotile", 256);
#ifdef DEBUG
imagecache->attribute ("statistics:level", 2);
#endif
// force a full diff, even for files tagged with the same
// fingerprint, just in case some mistake has been made.
imagecache->attribute ("deduplicate", 0);
ImageBuf img0, img1;
if (! read_input (filenames[0], img0, imagecache) ||
! read_input (filenames[1], img1, imagecache))
return ErrFile;
// ImageSpec spec0 = img0.spec(); // stash it
int ret = ErrOK;
for (int subimage = 0; subimage < img0.nsubimages(); ++subimage) {
if (subimage > 0 && !compareall)
break;
if (subimage >= img1.nsubimages())
break;
if (! read_input (filenames[0], img0, imagecache, subimage) ||
! read_input (filenames[1], img1, imagecache, subimage)) {
std::cout << "Failed to read subimage " << subimage << "\n";
return ErrFile;
}
if (img0.nmiplevels() != img1.nmiplevels()) {
std::cout << "Files do not match in their number of MIPmap levels\n";
}
for (int m = 0; m < img0.nmiplevels(); ++m) {
if (m > 0 && !compareall)
break;
if (m > 0 && img0.nmiplevels() != img1.nmiplevels()) {
std::cout << "Files do not match in their number of MIPmap levels\n";
ret = ErrDifferentSize;
break;
}
if (! read_input (filenames[0], img0, imagecache, subimage, m) ||
! read_input (filenames[1], img1, imagecache, subimage, m))
return ErrFile;
// Compare the dimensions of the images. Fail if they
// aren't the same resolution and number of channels. No
// problem, though, if they aren't the same data type.
if (! same_size (img0, img1)) {
print_subimage (img0, subimage, m);
std::cout << "Images do not match in size: ";
std::cout << "(" << img0.spec().width << "x" << img0.spec().height;
if (img0.spec().depth > 1)
std::cout << "x" << img0.spec().depth;
std::cout << "x" << img0.spec().nchannels << ")";
std::cout << " versus ";
std::cout << "(" << img1.spec().width << "x" << img1.spec().height;
if (img1.spec().depth > 1)
std::cout << "x" << img1.spec().depth;
std::cout << "x" << img1.spec().nchannels << ")\n";
ret = ErrDifferentSize;
break;
}
if (img0.deep() != img1.deep()) {
std::cout << "One image contains deep data, the other does not\n";
ret = ErrDifferentSize;
break;
}
int npels = img0.spec().width * img0.spec().height * img0.spec().depth;
if (npels == 0)
npels = 1; // Avoid divide by zero for 0x0 images
ASSERT (img0.spec().format == TypeDesc::FLOAT);
// Compare the two images.
//
ImageBufAlgo::CompareResults cr;
ImageBufAlgo::compare (img0, img1, failthresh, warnthresh, cr);
int yee_failures = 0;
if (perceptual && ! img0.deep())
yee_failures = ImageBufAlgo::compare_Yee (img0, img1);
if (cr.nfail > (failpercent/100.0 * npels) || cr.maxerror > hardfail ||
yee_failures > (failpercent/100.0 * npels)) {
//.........这里部分代码省略.........
示例11: test_texture3d
static void
test_texture3d (ustring filename)
{
std::cerr << "Testing 3d texture " << filename << ", output = "
<< output_filename << "\n";
const int nchannels = 4;
ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF);
ImageBuf image (output_filename, outspec);
ImageBufAlgo::zero (image);
Imath::M33f scale; scale.scale (Imath::V2f (0.5, 0.5));
Imath::M33f rot; rot.rotate (radians(30.0f));
Imath::M33f trans; trans.translate (Imath::V2f (0.35f, 0.15f));
Imath::M33f xform = scale * rot * trans;
xform.invert();
TextureOptions opt;
opt.sblur = blur;
opt.tblur = blur;
opt.rblur = blur;
opt.swidth = width;
opt.twidth = width;
opt.rwidth = width;
opt.nchannels = nchannels;
float fill = 0;
opt.fill = fill;
if (missing[0] >= 0)
opt.missingcolor.init ((float *)&missing, 0);
opt.swrap = opt.twrap = opt.rwrap = TextureOptions::WrapPeriodic;
int shadepoints = blocksize*blocksize;
Imath::V3f *P = ALLOCA (Imath::V3f, shadepoints);
Runflag *runflags = ALLOCA (Runflag, shadepoints);
Imath::V3f *dPdx = ALLOCA (Imath::V3f, shadepoints);
Imath::V3f *dPdy = ALLOCA (Imath::V3f, shadepoints);
Imath::V3f *dPdz = ALLOCA (Imath::V3f, shadepoints);
float *result = ALLOCA (float, shadepoints*nchannels);
for (int iter = 0; iter < iters; ++iter) {
// Iterate over blocks
// Trick: switch to second texture, if given, for second iteration
if (iter && filenames.size() > 1)
filename = ustring (filenames[1]);
for (int by = 0; by < output_yres; by+=blocksize) {
for (int bx = 0; bx < output_xres; bx+=blocksize) {
// Process pixels within a block. First save the texture warp
// (s,t) and derivatives into SIMD vectors.
int idx = 0;
for (int y = by; y < by+blocksize; ++y) {
for (int x = bx; x < bx+blocksize; ++x) {
if (x < output_xres && y < output_yres) {
if (nowarp) {
P[idx][0] = (float)x/output_xres * scalest;
P[idx][1] = (float)y/output_yres * scalest;
P[idx][2] = 0.5f * scalest;
P[idx] += offset;
dPdx[idx][0] = 1.0f/output_xres * scalest;
dPdx[idx][1] = 0;
dPdx[idx][2] = 0;
dPdy[idx][0] = 0;
dPdy[idx][1] = 1.0f/output_yres * scalest;
dPdy[idx][2] = 0;
dPdz[idx].setValue (0,0,0);
} else {
Imath::V3f coord = warp ((float)x/output_xres,
(float)y/output_yres,
0.5, xform);
coord *= scalest;
coord += offset;
Imath::V3f coordx = warp ((float)(x+1)/output_xres,
(float)y/output_yres,
0.5, xform);
coordx *= scalest;
coordx += offset;
Imath::V3f coordy = warp ((float)x/output_xres,
(float)(y+1)/output_yres,
0.5, xform);
coordy *= scalest;
coordy += offset;
P[idx] = coord;
dPdx[idx] = coordx - coord;
dPdy[idx] = coordy - coord;
dPdz[idx].setValue (0,0,0);
}
runflags[idx] = RunFlagOn;
} else {
runflags[idx] = RunFlagOff;
}
++idx;
}
}
// Call the texture system to do the filtering.
bool ok = texsys->texture3d (filename, opt, runflags, 0, shadepoints,
Varying(P), Varying(dPdx),
Varying(dPdy), Varying(dPdz),
result);
if (! ok) {
std::string e = texsys->geterror ();
//.........这里部分代码省略.........
示例12: test_plain_texture
static void
test_plain_texture ()
{
std::cerr << "Testing 2d texture " << filenames[0] << ", output = "
<< output_filename << "\n";
const int nchannels = 4;
ImageSpec outspec (output_xres, output_yres, nchannels, TypeDesc::HALF);
ImageBuf image (output_filename, outspec);
ImageBufAlgo::zero (image);
Imath::M33f scale; scale.scale (Imath::V2f (0.5, 0.5));
Imath::M33f rot; rot.rotate (radians(30.0f));
Imath::M33f trans; trans.translate (Imath::V2f (0.35f, 0.15f));
Imath::M33f xform = scale * rot * trans;
xform.invert();
TextureOptions opt;
opt.sblur = blur;
opt.tblur = blur;
opt.swidth = width;
opt.twidth = width;
opt.nchannels = nchannels;
float fill = 1;
opt.fill = fill;
if (missing[0] >= 0)
opt.missingcolor.init ((float *)&missing, 0);
// opt.interpmode = TextureOptions::InterpSmartBicubic;
// opt.mipmode = TextureOptions::MipModeAniso;
opt.swrap = opt.twrap = TextureOptions::WrapPeriodic;
// opt.twrap = TextureOptions::WrapBlack;
#if 1
TextureOpt opt1;
opt1.sblur = blur;
opt1.tblur = blur;
opt1.swidth = width;
opt1.twidth = width;
opt1.nchannels = nchannels;
opt1.fill = fill;
if (missing[0] >= 0)
opt1.missingcolor = (float *)&missing;
opt1.swrap = opt1.twrap = TextureOpt::WrapPeriodic;
#endif
int shadepoints = blocksize*blocksize;
float *s = ALLOCA (float, shadepoints);
float *t = ALLOCA (float, shadepoints);
Runflag *runflags = ALLOCA (Runflag, shadepoints);
float *dsdx = ALLOCA (float, shadepoints);
float *dtdx = ALLOCA (float, shadepoints);
float *dsdy = ALLOCA (float, shadepoints);
float *dtdy = ALLOCA (float, shadepoints);
float *result = ALLOCA (float, shadepoints*nchannels);
ustring filename = ustring (filenames[0]);
TextureSystem::Perthread *perthread_info = texsys->get_perthread_info ();
TextureSystem::TextureHandle *texture_handle = texsys->get_texture_handle (filename);
for (int iter = 0; iter < iters; ++iter) {
if (iters > 1 && filenames.size() > 1) {
// Use a different filename for each iteration
int texid = std::min (iter, (int)filenames.size()-1);
filename = ustring (filenames[texid]);
std::cerr << "iter " << iter << " file " << filename << "\n";
}
// Iterate over blocks
for (int by = 0, b = 0; by < output_yres; by+=blocksize) {
for (int bx = 0; bx < output_xres; bx+=blocksize, ++b) {
// Trick: switch to other textures on later iterations, if any
if (iters == 1 && filenames.size() > 1) {
// Use a different filename from block to block
filename = ustring (filenames[b % (int)filenames.size()]);
}
// Process pixels within a block. First save the texture warp
// (s,t) and derivatives into SIMD vectors.
int idx = 0;
for (int y = by; y < by+blocksize; ++y) {
for (int x = bx; x < bx+blocksize; ++x) {
if (x < output_xres && y < output_yres) {
if (nowarp) {
s[idx] = (float)x/output_xres * scalest + offset[0];
t[idx] = (float)y/output_yres + offset[1];
dsdx[idx] = 1.0f/output_xres * scalest * scalest;
dtdx[idx] = 0;
dsdy[idx] = 0;
dtdy[idx] = 1.0f/output_yres * scalest;
} else {
Imath::V3f coord = warp ((float)x/output_xres,
(float)y/output_yres,
xform);
coord *= scalest;
coord += offset;
Imath::V3f coordx = warp ((float)(x+1)/output_xres,
(float)y/output_yres,
xform);
coordx *= scalest;
coordx += offset;
Imath::V3f coordy = warp ((float)x/output_xres,
//.........这里部分代码省略.........
示例13: computePixelStats_
static bool
computePixelStats_ (const ImageBuf &src, ImageBufAlgo::PixelStats &stats,
ROI roi, int nthreads)
{
if (! roi.defined())
roi = get_roi (src.spec());
else
roi.chend = std::min (roi.chend, src.nchannels());
int nchannels = src.spec().nchannels;
// Use local storage for smaller batches, then merge the batches
// into the final results. This preserves precision for large
// images, where the running total may be too big to incorporate the
// contributions of individual pixel values without losing
// precision.
//
// This approach works best when the batch size is the sqrt of
// numpixels, which makes the num batches roughly equal to the
// number of pixels / batch.
ImageBufAlgo::PixelStats tmp;
reset (tmp, nchannels);
reset (stats, nchannels);
int PIXELS_PER_BATCH = std::max (1024,
static_cast<int>(sqrt((double)src.spec().image_pixels())));
if (src.deep()) {
// Loop over all pixels ...
for (ImageBuf::ConstIterator<T> s(src, roi); ! s.done(); ++s) {
int samples = s.deep_samples();
if (! samples)
continue;
for (int c = roi.chbegin; c < roi.chend; ++c) {
for (int i = 0; i < samples; ++i) {
float value = s.deep_value (c, i);
val (tmp, c, value);
if ((tmp.finitecount[c] % PIXELS_PER_BATCH) == 0) {
merge (stats, tmp);
reset (tmp, nchannels);
}
}
}
}
} else { // Non-deep case
// Loop over all pixels ...
for (ImageBuf::ConstIterator<T> s(src, roi); ! s.done(); ++s) {
for (int c = roi.chbegin; c < roi.chend; ++c) {
float value = s[c];
val (tmp, c, value);
if ((tmp.finitecount[c] % PIXELS_PER_BATCH) == 0) {
merge (stats, tmp);
reset (tmp, nchannels);
}
}
}
}
// Merge anything left over
merge (stats, tmp);
// Compute final results
finalize (stats);
return ! src.has_error();
};
示例14: switch
bool
ImageBuf::copy_pixels (const ImageBuf &src)
{
// compute overlap
int xbegin = std::max (this->xbegin(), src.xbegin());
int xend = std::min (this->xend(), src.xend());
int ybegin = std::max (this->ybegin(), src.ybegin());
int yend = std::min (this->yend(), src.yend());
int zbegin = std::max (this->zbegin(), src.zbegin());
int zend = std::min (this->zend(), src.zend());
int nchannels = std::min (this->nchannels(), src.nchannels());
// If we aren't copying over all our pixels, zero out the pixels
if (xbegin != this->xbegin() || xend != this->xend() ||
ybegin != this->ybegin() || yend != this->yend() ||
zbegin != this->zbegin() || zend != this->zend() ||
nchannels != this->nchannels())
ImageBufAlgo::zero (*this);
// Call template copy_pixels_ based on src data type
switch (src.spec().format.basetype) {
case TypeDesc::FLOAT :
copy_pixels_<float> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::UINT8 :
copy_pixels_<unsigned char> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::INT8 :
copy_pixels_<char> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::UINT16:
copy_pixels_<unsigned short> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::INT16 :
copy_pixels_<short> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::UINT :
copy_pixels_<unsigned int> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::INT :
copy_pixels_<int> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::HALF :
copy_pixels_<half> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::DOUBLE:
copy_pixels_<double> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::UINT64:
copy_pixels_<unsigned long long> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
case TypeDesc::INT64 :
copy_pixels_<long long> (*this, src, xbegin, xend, ybegin, yend,
zbegin, zend, nchannels);
break;
default:
ASSERT (0);
}
return true;
}
示例15: u_subimages
bool
ImageRec::read ()
{
if (elaborated())
return true;
static ustring u_subimages("subimages"), u_miplevels("miplevels");
static boost::regex regex_sha ("SHA-1=[[:xdigit:]]*[ ]*");
int subimages = 0;
ustring uname (name());
if (! m_imagecache->get_image_info (uname, 0, 0, u_subimages,
TypeDesc::TypeInt, &subimages)) {
error ("file not found: \"%s\"", name());
return false; // Image not found
}
m_subimages.resize (subimages);
bool allok = true;
for (int s = 0; s < subimages; ++s) {
int miplevels = 0;
m_imagecache->get_image_info (uname, s, 0, u_miplevels,
TypeDesc::TypeInt, &miplevels);
m_subimages[s].m_miplevels.resize (miplevels);
m_subimages[s].m_specs.resize (miplevels);
for (int m = 0; m < miplevels; ++m) {
// Force a read now for reasonable-sized first images in the
// file. This can greatly speed up the multithread case for
// tiled images by not having multiple threads working on the
// same image lock against each other on the file handle.
// We guess that "reasonable size" is 50 MB, that's enough to
// hold a 2048x1536 RGBA float image. Larger things will
// simply fall back on ImageCache.
bool forceread = (s == 0 && m == 0 &&
m_imagecache->imagespec(uname,s,m)->image_bytes() < 50*1024*1024);
ImageBuf *ib = new ImageBuf (name(), m_imagecache);
bool ok = ib->read (s, m, forceread,
TypeDesc::FLOAT /* force float */);
if (!ok)
error ("%s", ib->geterror());
allok &= ok;
// Remove any existing SHA-1 hash from the spec.
ib->specmod().erase_attribute ("oiio:SHA-1");
std::string desc = ib->spec().get_string_attribute ("ImageDescription");
if (desc.size())
ib->specmod().attribute ("ImageDescription",
boost::regex_replace (desc, regex_sha, ""));
m_subimages[s].m_miplevels[m].reset (ib);
m_subimages[s].m_specs[m] = ib->spec();
// For ImageRec purposes, we need to restore a few of the
// native settings.
const ImageSpec &nativespec (ib->nativespec());
// m_subimages[s].m_specs[m].format = nativespec.format;
m_subimages[s].m_specs[m].tile_width = nativespec.tile_width;
m_subimages[s].m_specs[m].tile_height = nativespec.tile_height;
m_subimages[s].m_specs[m].tile_depth = nativespec.tile_depth;
}
}
m_time = Filesystem::last_write_time (name());
m_elaborated = true;
return allok;
}