50 static const char* names[] = {
"triangle",
"quad" };
51 if (mt < 0 || mt >=
int(
sizeof(names)/
sizeof(
const char*)))
52 return "(invalid mesh type)";
59 static const char* names[] = {
"uint8",
"uint16",
"float16",
"float32" };
60 if (dt < 0 || dt >=
int(
sizeof(names)/
sizeof(
const char*)))
61 return "(invalid data type)";
68 static const char* names[] = {
"clamp",
"black",
"periodic" };
69 if (m < 0 || m >=
int(
sizeof(names)/
sizeof(
const char*)))
70 return "(invalid border mode)";
76 static const char* names[] = {
"none",
"tanvec" };
77 if (m < 0 || m >=
int(
sizeof(names)/
sizeof(
const char*)))
78 return "(invalid edge filter mode)";
85 static const char* names[] = {
"bottom",
"right",
"top",
"left" };
86 if (eid < 0 || eid >=
int(
sizeof(names)/
sizeof(
const char*)))
87 return "(invalid edge id)";
94 static const char* names[] = {
"string",
"int8",
"int16",
"int32",
"float",
"double" };
95 if (mdt < 0 || mdt >=
int(
sizeof(names)/
sizeof(
const char*)))
96 return "(invalid meta data type)";
102 template<
typename DST,
typename SRC>
103 void ConvertArrayClamped(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
105 for (
int i = 0; i < numChannels; i++)
109 template<
typename DST,
typename SRC>
110 void ConvertArray(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
112 for (
int i = 0; i < numChannels; i++)
113 dst[i] = DST((
float)src[i] * scale + round);
120 case dt_uint8: ConvertArray(dst, static_cast<const uint8_t*>(src), numChannels, 1.f/255.f);
break;
121 case dt_uint16: ConvertArray(dst, static_cast<const uint16_t*>(src), numChannels, 1.f/65535.f);
break;
122 case dt_half: ConvertArray(dst, static_cast<const PtexHalf*>(src), numChannels, 1.f);
break;
123 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
131 case dt_uint8: ConvertArrayClamped(static_cast<uint8_t*>(dst), src, numChannels, 255.0, 0.5);
break;
132 case dt_uint16: ConvertArrayClamped(static_cast<uint16_t*>(dst), src, numChannels, 65535.0, 0.5);
break;
133 case dt_half: ConvertArray(static_cast<PtexHalf*>(dst), src, numChannels, 1.0);
break;
134 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
141 bool isConstant(
const void* data,
int stride,
int ures,
int vres,
144 int rowlen = pixelSize * ures;
145 const char* p = (
const char*) data + stride;
148 for (
int i = 1; i < vres; i++, p += stride)
149 if (0 != memcmp(data, p, rowlen))
return 0;
152 p = (
const char*) data + pixelSize;
153 for (
int i = 1; i < ures; i++, p += pixelSize)
154 if (0 != memcmp(data, p, pixelSize))
return 0;
162 inline void interleave(
const T* src,
int sstride,
int uw,
int vw,
163 T* dst,
int dstride,
int nchan)
165 sstride /= (int)
sizeof(T);
166 dstride /= (int)
sizeof(T);
168 for (T* dstend = dst + nchan; dst != dstend; dst++) {
171 for (
const T* rowend = src + sstride*vw; src != rowend;
172 src += sstride, drow += dstride) {
175 for (
const T* sp = src, * end = sp + uw; sp != end; dp += nchan)
183 void interleave(
const void* src,
int sstride,
int uw,
int vw,
184 void* dst,
int dstride,
DataType dt,
int nchan)
188 (uint8_t*) dst, dstride, nchan);
break;
191 (uint16_t*) dst, dstride, nchan);
break;
193 (
float*) dst, dstride, nchan);
break;
199 inline void deinterleave(
const T* src,
int sstride,
int uw,
int vw,
200 T* dst,
int dstride,
int nchan)
202 sstride /= (int)
sizeof(T);
203 dstride /= (int)
sizeof(T);
205 for (
const T* srcend = src + nchan; src != srcend; src++) {
208 for (
const T* rowend = srow + sstride*vw; srow != rowend;
209 srow += sstride, dst += dstride) {
212 for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan)
221 void* dst,
int dstride,
DataType dt,
int nchan)
225 (uint8_t*) dst, dstride, nchan);
break;
228 (uint16_t*) dst, dstride, nchan);
break;
230 (
float*) dst, dstride, nchan);
break;
239 size /= (int)
sizeof(T);
240 T* p =
static_cast<T*
>(data), * end = p + size, tmp, prev = 0;
241 while (p != end) { tmp = prev; prev = *p; *p = T(*p - tmp); p++; }
259 size /= (int)
sizeof(T);
260 T* p =
static_cast<T*
>(data), * end = p + size, prev = 0;
261 while (p != end) { *p = T(*p + prev); prev = *p++; }
277 inline void reduce(
const T* src,
int sstride,
int uw,
int vw,
278 T* dst,
int dstride,
int nchan)
280 sstride /= (int)
sizeof(T);
281 dstride /= (int)
sizeof(T);
282 int rowlen = uw*nchan;
283 int srowskip = 2*sstride - rowlen;
284 int drowskip = dstride - rowlen/2;
285 for (
const T* end = src + vw*sstride; src != end;
286 src += srowskip, dst += drowskip)
287 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
288 for (
const T* pixend = src+nchan; src != pixend; src++)
289 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src[sstride+nchan]));
293 void reduce(
const void* src,
int sstride,
int uw,
int vw,
294 void* dst,
int dstride,
DataType dt,
int nchan)
297 case dt_uint8:
reduce(static_cast<const uint8_t*>(src), sstride, uw, vw,
298 static_cast<uint8_t*>(dst), dstride, nchan);
break;
299 case dt_half:
reduce(static_cast<const PtexHalf*>(src), sstride, uw, vw,
300 static_cast<PtexHalf*>(dst), dstride, nchan);
break;
301 case dt_uint16:
reduce(static_cast<const uint16_t*>(src), sstride, uw, vw,
302 static_cast<uint16_t*>(dst), dstride, nchan);
break;
303 case dt_float:
reduce(static_cast<const float*>(src), sstride, uw, vw,
304 static_cast<float*>(dst), dstride, nchan);
break;
311 inline void reduceu(
const T* src,
int sstride,
int uw,
int vw,
312 T* dst,
int dstride,
int nchan)
314 sstride /= (int)
sizeof(T);
315 dstride /= (int)
sizeof(T);
316 int rowlen = uw*nchan;
317 int srowskip = sstride - rowlen;
318 int drowskip = dstride - rowlen/2;
319 for (
const T* end = src + vw*sstride; src != end;
320 src += srowskip, dst += drowskip)
321 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
322 for (
const T* pixend = src+nchan; src != pixend; src++)
323 *dst++ = T(
halve(src[0] + src[nchan]));
327 void reduceu(
const void* src,
int sstride,
int uw,
int vw,
328 void* dst,
int dstride,
DataType dt,
int nchan)
331 case dt_uint8:
reduceu(static_cast<const uint8_t*>(src), sstride, uw, vw,
332 static_cast<uint8_t*>(dst), dstride, nchan);
break;
333 case dt_half:
reduceu(static_cast<const PtexHalf*>(src), sstride, uw, vw,
334 static_cast<PtexHalf*>(dst), dstride, nchan);
break;
336 static_cast<uint16_t*>(dst), dstride, nchan);
break;
337 case dt_float:
reduceu(static_cast<const float*>(src), sstride, uw, vw,
338 static_cast<float*>(dst), dstride, nchan);
break;
345 inline void reducev(
const T* src,
int sstride,
int uw,
int vw,
346 T* dst,
int dstride,
int nchan)
348 sstride /= (int)
sizeof(T);
349 dstride /= (int)
sizeof(T);
350 int rowlen = uw*nchan;
351 int srowskip = 2*sstride - rowlen;
352 int drowskip = dstride - rowlen;
353 for (
const T* end = src + vw*sstride; src != end;
354 src += srowskip, dst += drowskip)
355 for (
const T* rowend = src + rowlen; src != rowend; src++)
356 *dst++ = T(
halve(src[0] + src[sstride]));
360 void reducev(
const void* src,
int sstride,
int uw,
int vw,
361 void* dst,
int dstride,
DataType dt,
int nchan)
364 case dt_uint8:
reducev(static_cast<const uint8_t*>(src), sstride, uw, vw,
365 static_cast<uint8_t*>(dst), dstride, nchan);
break;
366 case dt_half:
reducev(static_cast<const PtexHalf*>(src), sstride, uw, vw,
367 static_cast<PtexHalf*>(dst), dstride, nchan);
break;
369 static_cast<uint16_t*>(dst), dstride, nchan);
break;
370 case dt_float:
reducev(static_cast<const float*>(src), sstride, uw, vw,
371 static_cast<float*>(dst), dstride, nchan);
break;
381 inline void reduceTri(
const T* src,
int sstride,
int w,
int ,
382 T* dst,
int dstride,
int nchan)
384 sstride /= (int)
sizeof(T);
385 dstride /= (int)
sizeof(T);
386 int rowlen = w*nchan;
387 const T* src2 = src + (w-1) * sstride + rowlen - nchan;
388 int srowinc2 = -2*sstride - nchan;
389 int srowskip = 2*sstride - rowlen;
390 int srowskip2 = w*sstride - 2 * nchan;
391 int drowskip = dstride - rowlen/2;
392 for (
const T* end = src + w*sstride; src != end;
393 src += srowskip, src2 += srowskip2, dst += drowskip)
394 for (
const T* rowend = src + rowlen; src != rowend; src += nchan, src2 += srowinc2)
395 for (
const T* pixend = src+nchan; src != pixend; src++, src2++)
396 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src2[0]));
400 void reduceTri(
const void* src,
int sstride,
int w,
int ,
401 void* dst,
int dstride,
DataType dt,
int nchan)
405 static_cast<uint8_t*>(dst), dstride, nchan);
break;
407 static_cast<PtexHalf*>(dst), dstride, nchan);
break;
409 static_cast<uint16_t*>(dst), dstride, nchan);
break;
411 static_cast<float*>(dst), dstride, nchan);
break;
416 void fill(
const void* src,
void* dst,
int dstride,
417 int ures,
int vres,
int pixelsize)
420 int rowlen = ures*pixelsize;
421 char* ptr = (
char*) dst;
422 char* end = ptr + rowlen;
423 for (; ptr != end; ptr += pixelsize) memcpy(ptr, src, pixelsize);
426 ptr = (
char*) dst + dstride;
427 end = (
char*) dst + vres*dstride;
428 for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen);
432 void copy(
const void* src,
int sstride,
void* dst,
int dstride,
433 int vres,
int rowlen)
436 if (sstride == rowlen && dstride == rowlen) {
438 memcpy(dst, src, vres*rowlen);
441 const char* sptr = (
const char*) src;
442 char* dptr = (
char*) dst;
443 for (
const char* end = sptr + vres*sstride; sptr != end;) {
444 memcpy(dptr, sptr, rowlen);
454 inline void blend(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
456 for (
const T* end = src + rowlen * nchan; src != end; dst++)
457 *dst = T(*dst + T(weight * (
float)*src++));
461 inline void blendflip(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
463 dst += (rowlen-1) * nchan;
464 for (
const T* end = src + rowlen * nchan; src != end;) {
465 for (
int i = 0; i < nchan; i++, dst++) {
466 *dst = T(*dst + T(weight * (
float)*src++));
474 void blend(
const void* src,
float weight,
void* dst,
bool flip,
477 switch ((dt<<1) |
int(flip)) {
478 case (
dt_uint8<<1):
blend(static_cast<const uint8_t*>(src), weight,
479 static_cast<uint8_t*>(dst), rowlen, nchan);
break;
480 case (
dt_uint8<<1 | 1): blendflip(static_cast<const uint8_t*>(src), weight,
481 static_cast<uint8_t*>(dst), rowlen, nchan);
break;
482 case (
dt_half<<1):
blend(static_cast<const PtexHalf*>(src), weight,
483 static_cast<PtexHalf*>(dst), rowlen, nchan);
break;
484 case (
dt_half<<1 | 1): blendflip(static_cast<const PtexHalf*>(src), weight,
485 static_cast<PtexHalf*>(dst), rowlen, nchan);
break;
486 case (
dt_uint16<<1):
blend(static_cast<const uint16_t*>(src), weight,
487 static_cast<uint16_t*>(dst), rowlen, nchan);
break;
488 case (
dt_uint16<<1 | 1): blendflip(static_cast<const uint16_t*>(src), weight,
489 static_cast<uint16_t*>(dst), rowlen, nchan);
break;
490 case (
dt_float<<1):
blend(static_cast<const float*>(src), weight,
491 static_cast<float*>(dst), rowlen, nchan);
break;
492 case (
dt_float<<1 | 1): blendflip(static_cast<const float*>(src), weight,
493 static_cast<float*>(dst), rowlen, nchan);
break;
500 inline void average(
const T* src,
int sstride,
int uw,
int vw,
503 float* buff = (
float*) alloca(nchan*
sizeof(
float));
504 memset(buff, 0, nchan*
sizeof(
float));
505 sstride /= (int)
sizeof(T);
506 int rowlen = uw*nchan;
507 int rowskip = sstride - rowlen;
508 for (
const T* end = src + vw*sstride; src != end; src += rowskip)
509 for (
const T* rowend = src + rowlen; src != rowend;)
510 for (
int i = 0; i < nchan; i++) buff[i] += (
float)*src++;
511 float scale = 1.0f/(float)(uw*vw);
512 for (
int i = 0; i < nchan; i++) dst[i] = T(buff[i]*scale);
516 void average(
const void* src,
int sstride,
int uw,
int vw,
520 case dt_uint8:
average(static_cast<const uint8_t*>(src), sstride, uw, vw,
521 static_cast<uint8_t*>(dst), nchan);
break;
522 case dt_half:
average(static_cast<const PtexHalf*>(src), sstride, uw, vw,
523 static_cast<PtexHalf*>(dst), nchan);
break;
525 static_cast<uint16_t*>(dst), nchan);
break;
526 case dt_float:
average(static_cast<const float*>(src), sstride, uw, vw,
527 static_cast<float*>(dst), nchan);
break;
533 struct CompareRfaceIds {
535 CompareRfaceIds(
const FaceInfo* facesArg) :
faces(facesArg) {}
536 bool operator() (uint32_t faceid1, uint32_t faceid2)
550 inline void multalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
554 if (alphachan == 0) {
558 nchanmult = nchannels - 1;
562 alphaoffset = alphachan;
563 nchanmult = alphachan;
566 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
567 float aval = scale * (float)data[alphaoffset];
568 for (
int i = 0; i < nchanmult; i++) data[i] = T((
float)data[i] * aval);
577 case dt_uint8:
multalpha(static_cast<uint8_t*>(data), npixels, nchannels, alphachan, scale);
break;
578 case dt_uint16:
multalpha(static_cast<uint16_t*>(data), npixels, nchannels, alphachan, scale);
break;
579 case dt_half:
multalpha(static_cast<PtexHalf*>(data), npixels, nchannels, alphachan, scale);
break;
580 case dt_float:
multalpha(static_cast<float*>(data), npixels, nchannels, alphachan, scale);
break;
587 inline void divalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
591 if (alphachan == 0) {
595 nchandiv = nchannels - 1;
599 alphaoffset = alphachan;
600 nchandiv = alphachan;
603 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
604 T alpha = data[alphaoffset];
605 if (!alpha)
continue;
606 float aval = scale / (float)alpha;
607 for (
int i = 0; i < nchandiv; i++) data[i] = T((
float)data[i] * aval);
616 case dt_uint8:
divalpha(static_cast<uint8_t*>(data), npixels, nchannels, alphachan, scale);
break;
617 case dt_uint16:
divalpha(static_cast<uint16_t*>(data), npixels, nchannels, alphachan, scale);
break;
618 case dt_half:
divalpha(static_cast<PtexHalf*>(data), npixels, nchannels, alphachan, scale);
break;
619 case dt_float:
divalpha(static_cast<float*>(data), npixels, nchannels, alphachan, scale);
break;
625 uint32_t* rfaceids, uint32_t* faceids)
631 for (
int i = 0; i < nfaces; i++) faceids[i] = i;
634 std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(
faces));
637 for (
int i = 0; i < nfaces; i++) {
639 rfaceids[faceids[i]] = i;
645 template<
class T,
int nChan>
646 void ApplyConst(
float weight,
float* dst,
void* data,
int )
649 VecAccum<T,nChan>()(dst, static_cast<T*>(data), weight);
654 void ApplyConstN(
float weight,
float* dst,
void* data,
int nChan)
657 VecAccumN<T>()(dst, static_cast<T*>(data), nChan, weight);
663 ApplyConstN<uint8_t>, ApplyConstN<uint16_t>, ApplyConstN<PtexHalf>, ApplyConstN<float>,
664 ApplyConst<uint8_t,1>, ApplyConst<uint16_t,1>, ApplyConst<PtexHalf,1>, ApplyConst<float,1>,
665 ApplyConst<uint8_t,2>, ApplyConst<uint16_t,2>, ApplyConst<PtexHalf,2>, ApplyConst<float,2>,
666 ApplyConst<uint8_t,3>, ApplyConst<uint16_t,3>, ApplyConst<PtexHalf,3>, ApplyConst<float,3>,
667 ApplyConst<uint8_t,4>, ApplyConst<uint16_t,4>, ApplyConst<PtexHalf,4>, ApplyConst<float,4>,
672 #ifndef PTEX_USE_STDSTRING 675 if (_str) free(_str);
679 String& String::operator=(
const char* str)
681 if (_str) free(_str);
682 _str = str ? strdup(str) : 0;
686 std::ostream&
operator << (std::ostream& stream,
const String& str)
688 stream << str.c_str();
bool isConstant(const void *data, int stride, int ures, int vres, int pixelSize)
void reducev(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void decodeDifference(void *data, int size, DataType dt)
Half-precision (16-bit) floating point.
PTEX_NAMESPACE_BEGIN const char * MeshTypeName(MeshType mt)
const char * MetaDataTypeName(MetaDataType mdt)
void(* ApplyConstFn)(float weight, float *dst, void *data, int nChan)
void deinterleave(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
const char * EdgeIdName(EdgeId eid)
const char * BorderModeName(BorderMode m)
Single-precision (32-bit) floating point.
EdgeFilterMode
How to handle transformation across edges when filtering.
void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
void reduce(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
EdgeId
Edge IDs used in adjacency data in the Ptex::FaceInfo struct.
void reduceTri(const void *src, int sstride, int w, int, void *dst, int dstride, DataType dt, int nchan)
void ConvertToFloat(float *dst, const void *src, DataType dt, int numChannels)
int8_t vlog2
log base 2 of v resolution, in texels
void average(const void *src, int sstride, int uw, int vw, void *dst, DataType dt, int nchan)
void blend(const void *src, float weight, void *dst, bool flip, int rowlen, DataType dt, int nchan)
MeshType
Type of base mesh for which the textures are defined.
Unsigned, 16-bit integer.
void encodeDifference(void *data, int size, DataType dt)
bool isConstant() const
Determine if face is constant (by checking a flag).
BorderMode
How to handle mesh border when filtering.
void ConvertFromFloat(void *dst, const float *src, DataType dt, int numChannels)
float OneValueInv(DataType dt)
Lookup up inverse value of given data type that corresponds to the normalized value of 1...
std::ostream & operator<<(std::ostream &stream, const Ptex::String &str)
std::stream output operator.
void reduceu(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
int8_t ulog2
log base 2 of u resolution, in texels
void divalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
Res res
Resolution of face.
MetaDataType
Type of meta data entry.
void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
Information about a face, as stored in the Ptex file header.
const char * EdgeFilterModeName(EdgeFilterMode m)
Half-precision floating-point type.
void interleave(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
ApplyConstFn applyConstFunctions[20]
DataType
Type of data stored in texture file.
const char * DataTypeName(DataType dt)
float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0. ...
#define PTEX_NAMESPACE_END
void copy(const void *src, int sstride, void *dst, int dstride, int vres, int rowlen)