47 static const char* names[] = {
"triangle",
"quad" };
48 if (mt < 0 || mt >=
int(
sizeof(names)/
sizeof(
const char*)))
49 return "(invalid mesh type)";
56 static const char* names[] = {
"uint8",
"uint16",
"float16",
"float32" };
57 if (dt < 0 || dt >=
int(
sizeof(names)/
sizeof(
const char*)))
58 return "(invalid data type)";
65 static const char* names[] = {
"clamp",
"black",
"periodic" };
66 if (m < 0 || m >=
int(
sizeof(names)/
sizeof(
const char*)))
67 return "(invalid border mode)";
74 static const char* names[] = {
"bottom",
"right",
"top",
"left" };
75 if (eid < 0 || eid >=
int(
sizeof(names)/
sizeof(
const char*)))
76 return "(invalid edge id)";
83 static const char* names[] = {
"string",
"int8",
"int16",
"int32",
"float",
"double" };
84 if (mdt < 0 || mdt >=
int(
sizeof(names)/
sizeof(
const char*)))
85 return "(invalid meta data type)";
92 template<
typename DST,
typename SRC>
93 void ConvertArrayClamped(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
95 for (
int i = 0; i < numChannels; i++)
99 template<
typename DST,
typename SRC>
100 void ConvertArray(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
102 for (
int i = 0; i < numChannels; i++)
103 dst[i] = DST((
float)src[i] * scale + round);
110 case dt_uint8: ConvertArray(dst, (uint8_t*)src, numChannels, 1.f/255.f);
break;
111 case dt_uint16: ConvertArray(dst, (uint16_t*)src, numChannels, 1.f/65535.f);
break;
112 case dt_half: ConvertArray(dst, (
PtexHalf*)src, numChannels, 1.f);
break;
113 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
121 case dt_uint8: ConvertArrayClamped((uint8_t*)dst, src, numChannels, 255.0, 0.5);
break;
122 case dt_uint16: ConvertArrayClamped((uint16_t*)dst, src, numChannels, 65535.0, 0.5);
break;
123 case dt_half: ConvertArray((
PtexHalf*)dst, src, numChannels, 1.0);
break;
124 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
132 int rowlen = pixelSize * ures;
133 const char* p = (
const char*) data + stride;
136 for (
int i = 1; i < vres; i++, p += stride)
137 if (0 != memcmp(data, p, rowlen))
return 0;
140 p = (
const char*) data + pixelSize;
141 for (
int i = 1; i < ures; i++, p += pixelSize)
142 if (0 != memcmp(data, p, pixelSize))
return 0;
150 inline void interleave(
const T* src,
int sstride,
int uw,
int vw,
151 T* dst,
int dstride,
int nchan)
153 sstride /= (int)
sizeof(T);
154 dstride /= (int)
sizeof(T);
156 for (T* dstend = dst + nchan; dst != dstend; dst++) {
159 for (
const T* rowend = src + sstride*vw; src != rowend;
160 src += sstride, drow += dstride) {
163 for (
const T* sp = src, * end = sp + uw; sp != end; dp += nchan)
172 void* dst,
int dstride,
DataType dt,
int nchan)
176 (uint8_t*) dst, dstride, nchan);
break;
179 (uint16_t*) dst, dstride, nchan);
break;
181 (
float*) dst, dstride, nchan);
break;
187 inline void deinterleave(
const T* src,
int sstride,
int uw,
int vw,
188 T* dst,
int dstride,
int nchan)
190 sstride /= (int)
sizeof(T);
191 dstride /= (int)
sizeof(T);
193 for (
const T* srcend = src + nchan; src != srcend; src++) {
196 for (
const T* rowend = srow + sstride*vw; srow != rowend;
197 srow += sstride, dst += dstride) {
200 for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan)
209 void* dst,
int dstride,
DataType dt,
int nchan)
213 (uint8_t*) dst, dstride, nchan);
break;
216 (uint16_t*) dst, dstride, nchan);
break;
218 (
float*) dst, dstride, nchan);
break;
225 void encodeDifference(T* data,
int size)
227 size /= (int)
sizeof(T);
228 T* p = (T*) data, * end = p + size, tmp, prev = 0;
229 while (p != end) { tmp = prev; prev = *p; *p = T(*p - tmp); p++; }
245 void decodeDifference(T* data,
int size)
247 size /= (int)
sizeof(T);
248 T* p = (T*) data, * end = p + size, prev = 0;
249 while (p != end) { *p = T(*p + prev); prev = *p++; }
265 inline void reduce(
const T* src,
int sstride,
int uw,
int vw,
266 T* dst,
int dstride,
int nchan)
268 sstride /= (int)
sizeof(T);
269 dstride /= (int)
sizeof(T);
270 int rowlen = uw*nchan;
271 int srowskip = 2*sstride - rowlen;
272 int drowskip = dstride - rowlen/2;
273 for (
const T* end = src + vw*sstride; src != end;
274 src += srowskip, dst += drowskip)
275 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
276 for (
const T* pixend = src+nchan; src != pixend; src++)
277 *dst++ = T(0.25 * (src[0] + src[nchan] +
278 src[sstride] + src[sstride+nchan]));
283 void* dst,
int dstride,
DataType dt,
int nchan)
287 (uint8_t*) dst, dstride, nchan);
break;
289 (
PtexHalf*) dst, dstride, nchan);
break;
291 (uint16_t*) dst, dstride, nchan);
break;
293 (
float*) dst, dstride, nchan);
break;
300 inline void reduceu(
const T* src,
int sstride,
int uw,
int vw,
301 T* dst,
int dstride,
int nchan)
303 sstride /= (int)
sizeof(T);
304 dstride /= (int)
sizeof(T);
305 int rowlen = uw*nchan;
306 int srowskip = sstride - rowlen;
307 int drowskip = dstride - rowlen/2;
308 for (
const T* end = src + vw*sstride; src != end;
309 src += srowskip, dst += drowskip)
310 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
311 for (
const T* pixend = src+nchan; src != pixend; src++)
312 *dst++ = T(0.5 * (src[0] + src[nchan]));
317 void* dst,
int dstride,
DataType dt,
int nchan)
321 (uint8_t*) dst, dstride, nchan);
break;
323 (
PtexHalf*) dst, dstride, nchan);
break;
325 (uint16_t*) dst, dstride, nchan);
break;
327 (
float*) dst, dstride, nchan);
break;
334 inline void reducev(
const T* src,
int sstride,
int uw,
int vw,
335 T* dst,
int dstride,
int nchan)
337 sstride /= (int)
sizeof(T);
338 dstride /= (int)
sizeof(T);
339 int rowlen = uw*nchan;
340 int srowskip = 2*sstride - rowlen;
341 int drowskip = dstride - rowlen;
342 for (
const T* end = src + vw*sstride; src != end;
343 src += srowskip, dst += drowskip)
344 for (
const T* rowend = src + rowlen; src != rowend; src++)
345 *dst++ = T(0.5 * (src[0] + src[sstride]));
350 void* dst,
int dstride,
DataType dt,
int nchan)
354 (uint8_t*) dst, dstride, nchan);
break;
356 (
PtexHalf*) dst, dstride, nchan);
break;
358 (uint16_t*) dst, dstride, nchan);
break;
360 (
float*) dst, dstride, nchan);
break;
370 inline void reduceTri(
const T* src,
int sstride,
int w,
int ,
371 T* dst,
int dstride,
int nchan)
373 sstride /= (int)
sizeof(T);
374 dstride /= (int)
sizeof(T);
375 int rowlen = w*nchan;
376 const T* src2 = src + (w-1) * sstride + rowlen - nchan;
377 int srowinc2 = -2*sstride - nchan;
378 int srowskip = 2*sstride - rowlen;
379 int srowskip2 = w*sstride - 2 * nchan;
380 int drowskip = dstride - rowlen/2;
381 for (
const T* end = src + w*sstride; src != end;
382 src += srowskip, src2 += srowskip2, dst += drowskip)
383 for (
const T* rowend = src + rowlen; src != rowend; src += nchan, src2 += srowinc2)
384 for (
const T* pixend = src+nchan; src != pixend; src++, src2++)
385 *dst++ = T(0.25 * (src[0] + src[nchan] + src[sstride] + src2[0]));
390 void* dst,
int dstride,
DataType dt,
int nchan)
394 (uint8_t*) dst, dstride, nchan);
break;
396 (
PtexHalf*) dst, dstride, nchan);
break;
398 (uint16_t*) dst, dstride, nchan);
break;
400 (
float*) dst, dstride, nchan);
break;
406 int ures,
int vres,
int pixelsize)
409 int rowlen = ures*pixelsize;
410 char* ptr = (
char*) dst;
411 char* end = ptr + rowlen;
412 for (; ptr != end; ptr += pixelsize) memcpy(ptr, src, pixelsize);
415 ptr = (
char*) dst + dstride;
416 end = (
char*) dst + vres*dstride;
417 for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen);
422 int vres,
int rowlen)
425 if (sstride == rowlen && dstride == rowlen) {
427 memcpy(dst, src, vres*rowlen);
430 char* sptr = (
char*) src;
431 char* dptr = (
char*) dst;
432 for (
char* end = sptr + vres*sstride; sptr != end;) {
433 memcpy(dptr, sptr, rowlen);
443 inline void blend(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
445 for (
const T* end = src + rowlen * nchan; src != end; dst++)
446 *dst = T(*dst + T(weight * (
float)*src++));
450 inline void blendflip(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
452 dst += (rowlen-1) * nchan;
453 for (
const T* end = src + rowlen * nchan; src != end;) {
454 for (
int i = 0; i < nchan; i++, dst++) {
455 *dst = T(*dst + T(weight * (
float)*src++));
466 switch ((dt<<1) |
int(flip)) {
468 (uint8_t*) dst, rowlen, nchan);
break;
469 case (
dt_uint8<<1 | 1): ::blendflip((
const uint8_t*) src, weight,
470 (uint8_t*) dst, rowlen, nchan);
break;
472 (
PtexHalf*) dst, rowlen, nchan);
break;
474 (
PtexHalf*) dst, rowlen, nchan);
break;
476 (uint16_t*) dst, rowlen, nchan);
break;
477 case (
dt_uint16<<1 | 1): ::blendflip((
const uint16_t*) src, weight,
478 (uint16_t*) dst, rowlen, nchan);
break;
480 (
float*) dst, rowlen, nchan);
break;
481 case (
dt_float<<1 | 1): ::blendflip((
const float*) src, weight,
482 (
float*) dst, rowlen, nchan);
break;
489 inline void average(
const T* src,
int sstride,
int uw,
int vw,
492 float* buff = (
float*) alloca(nchan*
sizeof(
float));
493 memset(buff, 0, nchan*
sizeof(
float));
494 sstride /= (int)
sizeof(T);
495 int rowlen = uw*nchan;
496 int rowskip = sstride - rowlen;
497 for (
const T* end = src + vw*sstride; src != end; src += rowskip)
498 for (
const T* rowend = src + rowlen; src != rowend;)
499 for (
int i = 0; i < nchan; i++) buff[i] += (
float)*src++;
500 float scale = 1.0f/(float)(uw*vw);
501 for (
int i = 0; i < nchan; i++) dst[i] = T(buff[i]*scale);
510 (uint8_t*) dst, nchan);
break;
514 (uint16_t*) dst, nchan);
break;
516 (
float*) dst, nchan);
break;
522 struct CompareRfaceIds {
525 bool operator() (uint32_t faceid1, uint32_t faceid2)
539 inline void multalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
543 if (alphachan == 0) {
547 nchanmult = nchannels - 1;
551 alphaoffset = alphachan;
552 nchanmult = alphachan;
555 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
556 float aval = scale * (float)data[alphaoffset];
557 for (
int i = 0; i < nchanmult; i++) data[i] = T((
float)data[i] * aval);
576 inline void divalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
580 if (alphachan == 0) {
584 nchandiv = nchannels - 1;
588 alphaoffset = alphachan;
589 nchandiv = alphachan;
592 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
593 T alpha = data[alphaoffset];
594 if (!alpha)
continue;
595 float aval = scale / (float)alpha;
596 for (
int i = 0; i < nchandiv; i++) data[i] = T((
float)data[i] * aval);
605 case dt_uint8:
::divalpha((uint8_t*) data, npixels, nchannels, alphachan, scale);
break;
608 case dt_float:
::divalpha((
float*) data, npixels, nchannels, alphachan, scale);
break;
614 uint32_t* rfaceids, uint32_t* faceids)
620 for (
int i = 0; i < nfaces; i++) faceids[i] = i;
623 std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(faces));
626 for (
int i = 0; i < nfaces; i++) {
628 rfaceids[faceids[i]] = i;
634 template<
class T,
int nChan>
635 void ApplyConst(
float weight,
float* dst,
void* data,
int )
643 void ApplyConstN(
float weight,
float* dst,
void* data,
int nChan)
652 ApplyConstN<uint8_t>, ApplyConstN<uint16_t>, ApplyConstN<PtexHalf>, ApplyConstN<float>,
653 ApplyConst<uint8_t,1>, ApplyConst<uint16_t,1>, ApplyConst<PtexHalf,1>, ApplyConst<float,1>,
654 ApplyConst<uint8_t,2>, ApplyConst<uint16_t,2>, ApplyConst<PtexHalf,2>, ApplyConst<float,2>,
655 ApplyConst<uint8_t,3>, ApplyConst<uint16_t,3>, ApplyConst<PtexHalf,3>, ApplyConst<float,3>,
656 ApplyConst<uint8_t,4>, ApplyConst<uint16_t,4>, ApplyConst<PtexHalf,4>, ApplyConst<float,4>,
659 #ifndef PTEX_USE_STDSTRING
662 if (_str) free(_str);
668 if (_str) free(_str);
669 _str = str ? strdup(str) : 0;
675 stream << str.
c_str();
static float OneValueInv(DataType dt)
Lookup up inverse value of given data type that corresponds to the normalized value of 1...
static void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
bool isConstant() const
Determine if face is constant (by checking a flag).
Unsigned, 16-bit integer.
static void reduceTri(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Half-precision (16-bit) floating point.
DataType
Type of data stored in texture file.
static void blend(const void *src, float weight, void *dst, bool flip, int rowlen, DataType dt, int nchannels)
void(* ApplyConstFn)(float weight, float *dst, void *data, int nChan)
static void average(const void *src, int sstride, int ures, int vres, void *dst, DataType dt, int nchannels)
String & operator=(const char *str)
static void copy(const void *src, int sstride, void *dst, int dstride, int nrows, int rowlen)
MetaDataType
Type of meta data entry.
static float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0. ...
static const char * MeshTypeName(MeshType mt)
Look up name of given mesh type.
static ApplyConstFn applyConstFunctions[20]
BorderMode
How to handle mesh border when filtering.
int8_t vlog2
log base 2 of v resolution, in texels
static T clamp(T x, T lo, T hi)
static void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
Single-precision (32-bit) floating point.
std::ostream & operator<<(std::ostream &stream, const Ptex::String &str)
Half-precision (16-bit) floating-point type.
static const char * DataTypeName(DataType dt)
Look up name of given data type.
MeshType
Type of base mesh for which the textures are defined.
static void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
static void encodeDifference(void *data, int size, DataType dt)
static const char * MetaDataTypeName(MetaDataType mdt)
Look up name of given meta data type.
int8_t ulog2
log base 2 of u resolution, in texels
static const char * BorderModeName(BorderMode m)
Look up name of given border mode.
static void divalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
static void deinterleave(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static void reduceu(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static void interleave(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static void reducev(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Res res
Resolution of face.
Information about a face, as stored in the Ptex file header.
Half-precision floating-point type.
static void decodeDifference(void *data, int size, DataType dt)
static void ConvertToFloat(float *dst, const void *src, Ptex::DataType dt, int numChannels)
Convert a number of data values from the given data type to float.
static void reduce(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
static void ConvertFromFloat(void *dst, const float *src, Ptex::DataType dt, int numChannels)
Convert a number of data values from float to the given data type.
const char * c_str() const
static bool isConstant(const void *data, int stride, int ures, int vres, int pixelSize)
static const char * EdgeIdName(EdgeId eid)
Look up name of given edge ID.
EdgeId
Edge IDs used in adjacency data in the Ptex::FaceInfo struct.