Ptex: PtexUtils.cpp Source File

Ptex

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

PtexUtils.cpp
Go to the documentation of this file.
1 /*
2 PTEX SOFTWARE
3 Copyright 2009 Disney Enterprises, Inc. All rights reserved
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
18 Studios" or the names of its contributors may NOT be used to
19 endorse or promote products derived from this software without
20 specific prior written permission from Walt Disney Pictures.
21
22 Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
25 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
26 IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
31 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 */
35
36 #include "PtexPlatform.h"
37 #include <algorithm>
38 #include <vector>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "PtexHalf.h"
43 #include "PtexUtils.h"
44
45 const char* Ptex::MeshTypeName(MeshType mt)
46 {
47 static const char* names[] = { "triangle", "quad" };
48 if (mt < 0 || mt >= int(sizeof(names)/sizeof(const char*)))
49 return "(invalid mesh type)";
50 return names[mt];
51 }
52
53
54 const char* Ptex::DataTypeName(DataType dt)
55 {
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)";
59 return names[dt];
60 }
61
62
63 const char* Ptex::BorderModeName(BorderMode m)
64 {
65 static const char* names[] = { "clamp", "black", "periodic" };
66 if (m < 0 || m >= int(sizeof(names)/sizeof(const char*)))
67 return "(invalid border mode)";
68 return names[m];
69 }
70
71
72 const char* Ptex::EdgeIdName(EdgeId eid)
73 {
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)";
77 return names[eid];
78 }
79
80
81 const char* Ptex::MetaDataTypeName(MetaDataType mdt)
82 {
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)";
86 return names[mdt];
87 }
88
89
90
91 namespace {
92 template<typename DST, typename SRC>
93 void ConvertArrayClamped(DST* dst, SRC* src, int numChannels, float scale, float round=0)
94 {
95 for (int i = 0; i < numChannels; i++)
96 dst[i] = DST(PtexUtils::clamp(src[i], 0.0f, 1.0f) * scale + round);
97 }
98
99 template<typename DST, typename SRC>
100 void ConvertArray(DST* dst, SRC* src, int numChannels, float scale, float round=0)
101 {
102 for (int i = 0; i < numChannels; i++)
103 dst[i] = DST((float)src[i] * scale + round);
104 }
105 }
106
107 void Ptex::ConvertToFloat(float* dst, const void* src, Ptex::DataType dt, int numChannels)
108 {
109 switch (dt) {
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;
114 }
115 }
116
117
118 void Ptex::ConvertFromFloat(void* dst, const float* src, Ptex::DataType dt, int numChannels)
119 {
120 switch (dt) {
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;
125 }
126 }
127
128
129 bool PtexUtils::isConstant(const void* data, int stride, int ures, int vres,
130 int pixelSize)
131 {
132 int rowlen = pixelSize * ures;
133 const char* p = (const char*) data + stride;
134
135 // compare each row with the first
136 for (int i = 1; i < vres; i++, p += stride)
137 if (0 != memcmp(data, p, rowlen)) return 0;
138
139 // make sure first row is constant
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;
143
144 return 1;
145 }
146
147
148 namespace {
149 template<typename T>
150 inline void interleave(const T* src, int sstride, int uw, int vw,
151 T* dst, int dstride, int nchan)
152 {
153 sstride /= (int)sizeof(T);
154 dstride /= (int)sizeof(T);
155 // for each channel
156 for (T* dstend = dst + nchan; dst != dstend; dst++) {
157 // for each row
158 T* drow = dst;
159 for (const T* rowend = src + sstride*vw; src != rowend;
160 src += sstride, drow += dstride) {
161 // copy each pixel across the row
162 T* dp = drow;
163 for (const T* sp = src, * end = sp + uw; sp != end; dp += nchan)
164 *dp = *sp++;
165 }
166 }
167 }
168 }
169
170
171 void PtexUtils::interleave(const void* src, int sstride, int uw, int vw,
172 void* dst, int dstride, DataType dt, int nchan)
173 {
174 switch (dt) {
175 case dt_uint8: ::interleave((const uint8_t*) src, sstride, uw, vw,
176 (uint8_t*) dst, dstride, nchan); break;
177 case dt_half:
178 case dt_uint16: ::interleave((const uint16_t*) src, sstride, uw, vw,
179 (uint16_t*) dst, dstride, nchan); break;
180 case dt_float: ::interleave((const float*) src, sstride, uw, vw,
181 (float*) dst, dstride, nchan); break;
182 }
183 }
184
185 namespace {
186 template<typename T>
187 inline void deinterleave(const T* src, int sstride, int uw, int vw,
188 T* dst, int dstride, int nchan)
189 {
190 sstride /= (int)sizeof(T);
191 dstride /= (int)sizeof(T);
192 // for each channel
193 for (const T* srcend = src + nchan; src != srcend; src++) {
194 // for each row
195 const T* srow = src;
196 for (const T* rowend = srow + sstride*vw; srow != rowend;
197 srow += sstride, dst += dstride) {
198 // copy each pixel across the row
199 const T* sp = srow;
200 for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan)
201 *dp++ = *sp;
202 }
203 }
204 }
205 }
206
207
208 void PtexUtils::deinterleave(const void* src, int sstride, int uw, int vw,
209 void* dst, int dstride, DataType dt, int nchan)
210 {
211 switch (dt) {
212 case dt_uint8: ::deinterleave((const uint8_t*) src, sstride, uw, vw,
213 (uint8_t*) dst, dstride, nchan); break;
214 case dt_half:
215 case dt_uint16: ::deinterleave((const uint16_t*) src, sstride, uw, vw,
216 (uint16_t*) dst, dstride, nchan); break;
217 case dt_float: ::deinterleave((const float*) src, sstride, uw, vw,
218 (float*) dst, dstride, nchan); break;
219 }
220 }
221
222
223 namespace {
224 template<typename T>
225 void encodeDifference(T* data, int size)
226 {
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++; }
230 }
231 }
232
233 void PtexUtils::encodeDifference(void* data, int size, DataType dt)
234 {
235 switch (dt) {
236 case dt_uint8: ::encodeDifference((uint8_t*) data, size); break;
237 case dt_uint16: ::encodeDifference((uint16_t*) data, size); break;
238 default: break; // skip other types
239 }
240 }
241
242
243 namespace {
244 template<typename T>
245 void decodeDifference(T* data, int size)
246 {
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++; }
250 }
251 }
252
253 void PtexUtils::decodeDifference(void* data, int size, DataType dt)
254 {
255 switch (dt) {
256 case dt_uint8: ::decodeDifference((uint8_t*) data, size); break;
257 case dt_uint16: ::decodeDifference((uint16_t*) data, size); break;
258 default: break; // skip other types
259 }
260 }
261
262
263 namespace {
264 template<typename T>
265 inline void reduce(const T* src, int sstride, int uw, int vw,
266 T* dst, int dstride, int nchan)
267 {
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]));
279 }
280 }
281
282 void PtexUtils::reduce(const void* src, int sstride, int uw, int vw,
283 void* dst, int dstride, DataType dt, int nchan)
284 {
285 switch (dt) {
286 case dt_uint8: ::reduce((const uint8_t*) src, sstride, uw, vw,
287 (uint8_t*) dst, dstride, nchan); break;
288 case dt_half: ::reduce((const PtexHalf*) src, sstride, uw, vw,
289 (PtexHalf*) dst, dstride, nchan); break;
290 case dt_uint16: ::reduce((const uint16_t*) src, sstride, uw, vw,
291 (uint16_t*) dst, dstride, nchan); break;
292 case dt_float: ::reduce((const float*) src, sstride, uw, vw,
293 (float*) dst, dstride, nchan); break;
294 }
295 }
296
297
298 namespace {
299 template<typename T>
300 inline void reduceu(const T* src, int sstride, int uw, int vw,
301 T* dst, int dstride, int nchan)
302 {
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]));
313 }
314 }
315
316 void PtexUtils::reduceu(const void* src, int sstride, int uw, int vw,
317 void* dst, int dstride, DataType dt, int nchan)
318 {
319 switch (dt) {
320 case dt_uint8: ::reduceu((const uint8_t*) src, sstride, uw, vw,
321 (uint8_t*) dst, dstride, nchan); break;
322 case dt_half: ::reduceu((const PtexHalf*) src, sstride, uw, vw,
323 (PtexHalf*) dst, dstride, nchan); break;
324 case dt_uint16: ::reduceu((const uint16_t*) src, sstride, uw, vw,
325 (uint16_t*) dst, dstride, nchan); break;
326 case dt_float: ::reduceu((const float*) src, sstride, uw, vw,
327 (float*) dst, dstride, nchan); break;
328 }
329 }
330
331
332 namespace {
333 template<typename T>
334 inline void reducev(const T* src, int sstride, int uw, int vw,
335 T* dst, int dstride, int nchan)
336 {
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]));
346 }
347 }
348
349 void PtexUtils::reducev(const void* src, int sstride, int uw, int vw,
350 void* dst, int dstride, DataType dt, int nchan)
351 {
352 switch (dt) {
353 case dt_uint8: ::reducev((const uint8_t*) src, sstride, uw, vw,
354 (uint8_t*) dst, dstride, nchan); break;
355 case dt_half: ::reducev((const PtexHalf*) src, sstride, uw, vw,
356 (PtexHalf*) dst, dstride, nchan); break;
357 case dt_uint16: ::reducev((const uint16_t*) src, sstride, uw, vw,
358 (uint16_t*) dst, dstride, nchan); break;
359 case dt_float: ::reducev((const float*) src, sstride, uw, vw,
360 (float*) dst, dstride, nchan); break;
361 }
362 }
363
364
365
366 namespace {
367 // generate a reduction of a packed-triangle texture
368 // note: this method won't work for tiled textures
369 template<typename T>
370 inline void reduceTri(const T* src, int sstride, int w, int /*vw*/,
371 T* dst, int dstride, int nchan)
372 {
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]));
386 }
387 }
388
389 void PtexUtils::reduceTri(const void* src, int sstride, int w, int /*vw*/,
390 void* dst, int dstride, DataType dt, int nchan)
391 {
392 switch (dt) {
393 case dt_uint8: ::reduceTri((const uint8_t*) src, sstride, w, 0,
394 (uint8_t*) dst, dstride, nchan); break;
395 case dt_half: ::reduceTri((const PtexHalf*) src, sstride, w, 0,
396 (PtexHalf*) dst, dstride, nchan); break;
397 case dt_uint16: ::reduceTri((const uint16_t*) src, sstride, w, 0,
398 (uint16_t*) dst, dstride, nchan); break;
399 case dt_float: ::reduceTri((const float*) src, sstride, w, 0,
400 (float*) dst, dstride, nchan); break;
401 }
402 }
403
404
405 void PtexUtils::fill(const void* src, void* dst, int dstride,
406 int ures, int vres, int pixelsize)
407 {
408 // fill first row
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);
413
414 // fill remaining rows from first row
415 ptr = (char*) dst + dstride;
416 end = (char*) dst + vres*dstride;
417 for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen);
418 }
419
420
421 void PtexUtils::copy(const void* src, int sstride, void* dst, int dstride,
422 int vres, int rowlen)
423 {
424 // regular non-tiled case
425 if (sstride == rowlen && dstride == rowlen) {
426 // packed case - copy in single block
427 memcpy(dst, src, vres*rowlen);
428 } else {
429 // copy a row at a time
430 char* sptr = (char*) src;
431 char* dptr = (char*) dst;
432 for (char* end = sptr + vres*sstride; sptr != end;) {
433 memcpy(dptr, sptr, rowlen);
434 dptr += dstride;
435 sptr += sstride;
436 }
437 }
438 }
439
440
441 namespace {
442 template<typename T>
443 inline void blend(const T* src, float weight, T* dst, int rowlen, int nchan)
444 {
445 for (const T* end = src + rowlen * nchan; src != end; dst++)
446 *dst = T(*dst + T(weight * (float)*src++));
447 }
448
449 template<typename T>
450 inline void blendflip(const T* src, float weight, T* dst, int rowlen, int nchan)
451 {
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++));
456 }
457 dst -= nchan*2;
458 }
459 }
460 }
461
462
463 void PtexUtils::blend(const void* src, float weight, void* dst, bool flip,
464 int rowlen, DataType dt, int nchan)
465 {
466 switch ((dt<<1) | int(flip)) {
467 case (dt_uint8<<1): ::blend((const uint8_t*) src, weight,
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;
471 case (dt_half<<1): ::blend((const PtexHalf*) src, weight,
472 (PtexHalf*) dst, rowlen, nchan); break;
473 case (dt_half<<1 | 1): ::blendflip((const PtexHalf*) src, weight,
474 (PtexHalf*) dst, rowlen, nchan); break;
475 case (dt_uint16<<1): ::blend((const uint16_t*) src, weight,
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;
479 case (dt_float<<1): ::blend((const float*) src, weight,
480 (float*) dst, rowlen, nchan); break;
481 case (dt_float<<1 | 1): ::blendflip((const float*) src, weight,
482 (float*) dst, rowlen, nchan); break;
483 }
484 }
485
486
487 namespace {
488 template<typename T>
489 inline void average(const T* src, int sstride, int uw, int vw,
490 T* dst, int nchan)
491 {
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);
502 }
503 }
504
505 void PtexUtils::average(const void* src, int sstride, int uw, int vw,
506 void* dst, DataType dt, int nchan)
507 {
508 switch (dt) {
509 case dt_uint8: ::average((const uint8_t*) src, sstride, uw, vw,
510 (uint8_t*) dst, nchan); break;
511 case dt_half: ::average((const PtexHalf*) src, sstride, uw, vw,
512 (PtexHalf*) dst, nchan); break;
513 case dt_uint16: ::average((const uint16_t*) src, sstride, uw, vw,
514 (uint16_t*) dst, nchan); break;
515 case dt_float: ::average((const float*) src, sstride, uw, vw,
516 (float*) dst, nchan); break;
517 }
518 }
519
520
521 namespace {
522 struct CompareRfaceIds {
523 const Ptex::FaceInfo* faces;
524 CompareRfaceIds(const Ptex::FaceInfo* faces) : faces(faces) {}
525 bool operator() (uint32_t faceid1, uint32_t faceid2)
526 {
527 const Ptex::FaceInfo& f1 = faces[faceid1];
528 const Ptex::FaceInfo& f2 = faces[faceid2];
529 int min1 = f1.isConstant() ? 1 : PtexUtils::min(f1.res.ulog2, f1.res.vlog2);
530 int min2 = f2.isConstant() ? 1 : PtexUtils::min(f2.res.ulog2, f2.res.vlog2);
531 return min1 > min2;
532 }
533 };
534 }
535
536
537 namespace {
538 template<typename T>
539 inline void multalpha(T* data, int npixels, int nchannels, int alphachan, float scale)
540 {
541 int alphaoffset; // offset to alpha chan from data ptr
542 int nchanmult; // number of channels to alpha-multiply
543 if (alphachan == 0) {
544 // first channel is alpha chan: mult the rest of the channels
545 data++;
546 alphaoffset = -1;
547 nchanmult = nchannels - 1;
548 }
549 else {
550 // mult all channels up to alpha chan
551 alphaoffset = alphachan;
552 nchanmult = alphachan;
553 }
554
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);
558 }
559 }
560 }
561
562 void PtexUtils::multalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan)
563 {
564 float scale = OneValueInv(dt);
565 switch(dt) {
566 case dt_uint8: ::multalpha((uint8_t*) data, npixels, nchannels, alphachan, scale); break;
567 case dt_uint16: ::multalpha((uint16_t*) data, npixels, nchannels, alphachan, scale); break;
568 case dt_half: ::multalpha((PtexHalf*) data, npixels, nchannels, alphachan, scale); break;
569 case dt_float: ::multalpha((float*) data, npixels, nchannels, alphachan, scale); break;
570 }
571 }
572
573
574 namespace {
575 template<typename T>
576 inline void divalpha(T* data, int npixels, int nchannels, int alphachan, float scale)
577 {
578 int alphaoffset; // offset to alpha chan from data ptr
579 int nchandiv; // number of channels to alpha-divide
580 if (alphachan == 0) {
581 // first channel is alpha chan: div the rest of the channels
582 data++;
583 alphaoffset = -1;
584 nchandiv = nchannels - 1;
585 }
586 else {
587 // div all channels up to alpha chan
588 alphaoffset = alphachan;
589 nchandiv = alphachan;
590 }
591
592 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
593 T alpha = data[alphaoffset];
594 if (!alpha) continue; // don't divide by zero!
595 float aval = scale / (float)alpha;
596 for (int i = 0; i < nchandiv; i++) data[i] = T((float)data[i] * aval);
597 }
598 }
599 }
600
601 void PtexUtils::divalpha(void* data, int npixels, DataType dt, int nchannels, int alphachan)
602 {
603 float scale = OneValue(dt);
604 switch(dt) {
605 case dt_uint8: ::divalpha((uint8_t*) data, npixels, nchannels, alphachan, scale); break;
606 case dt_uint16: ::divalpha((uint16_t*) data, npixels, nchannels, alphachan, scale); break;
607 case dt_half: ::divalpha((PtexHalf*) data, npixels, nchannels, alphachan, scale); break;
608 case dt_float: ::divalpha((float*) data, npixels, nchannels, alphachan, scale); break;
609 }
610 }
611
612
613 void PtexUtils::genRfaceids(const FaceInfo* faces, int nfaces,
614 uint32_t* rfaceids, uint32_t* faceids)
615 {
616 // stable_sort faceids by smaller dimension (u or v) in descending order
617 // treat const faces as having res of 1
618
619 // init faceids
620 for (int i = 0; i < nfaces; i++) faceids[i] = i;
621
622 // sort faceids by rfaceid
623 std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(faces));
624
625 // generate mapping from faceid to rfaceid
626 for (int i = 0; i < nfaces; i++) {
627 // note: i is the rfaceid
628 rfaceids[faceids[i]] = i;
629 }
630 }
631
632 namespace {
633 // apply to 1..4 channels, unrolled
634 template<class T, int nChan>
635 void ApplyConst(float weight, float* dst, void* data, int /*nChan*/)
636 {
637 // dst[i] += data[i] * weight for i in {0..n-1}
638 PtexUtils::VecAccum<T,nChan>()(dst, (T*) data, weight);
639 }
640
641 // apply to N channels (general case)
642 template<class T>
643 void ApplyConstN(float weight, float* dst, void* data, int nChan)
644 {
645 // dst[i] += data[i] * weight for i in {0..n-1}
646 PtexUtils::VecAccumN<T>()(dst, (T*) data, nChan, weight);
647 }
648 }
649
650 PtexUtils::ApplyConstFn
651 PtexUtils::applyConstFunctions[20] = {
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>,
657 };
658
659 #ifndef PTEX_USE_STDSTRING
660 Ptex::String::~String()
661 {
662 if (_str) free(_str);
663 }
664
665
666 Ptex::String& Ptex::String::operator=(const char* str)
667 {
668 if (_str) free(_str);
669 _str = str ? strdup(str) : 0;
670 return *this;
671 }
672
673 std::ostream& operator << (std::ostream& stream, const Ptex::String& str)
674 {
675 stream << str.c_str();
676 return stream;
677 }
678 #endif
679
Ptex::OneValueInv
static float OneValueInv(DataType dt)
Lookup up inverse value of given data type that corresponds to the normalized value of 1...
Definition: Ptexture.h:144
Ptex::dt_uint8
Unsigned, 8-bit integer.
Definition: Ptexture.h:84
Ptex::String::~String
~String()
Definition: PtexUtils.cpp:660
PtexUtils::multalpha
static void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
Definition: PtexUtils.cpp:562
Ptex::FaceInfo::isConstant
bool isConstant() const
Determine if face is constant (by checking a flag).
Definition: Ptexture.h:270
Ptex::dt_uint16
Unsigned, 16-bit integer.
Definition: Ptexture.h:85
Ptex::String
Memory-managed string.
Definition: Ptexture.h:303
PtexUtils::reduceTri
static void reduceTri(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:389
Ptex::dt_half
Half-precision (16-bit) floating point.
Definition: Ptexture.h:86
Ptex::DataType
DataType
Type of data stored in texture file.
Definition: Ptexture.h:83
PtexUtils::blend
static void blend(const void *src, float weight, void *dst, bool flip, int rowlen, DataType dt, int nchannels)
Definition: PtexUtils.cpp:463
PtexUtils::ApplyConstFn
void(* ApplyConstFn)(float weight, float *dst, void *data, int nChan)
Definition: PtexUtils.h:202
PtexUtils::average
static void average(const void *src, int sstride, int ures, int vres, void *dst, DataType dt, int nchannels)
Definition: PtexUtils.cpp:505
PtexUtils::min
static T min(T a, T b)
Definition: PtexUtils.h:116
Ptex::String::operator=
String & operator=(const char *str)
Definition: PtexUtils.cpp:666
PtexUtils::copy
static void copy(const void *src, int sstride, void *dst, int dstride, int nrows, int rowlen)
Definition: PtexUtils.cpp:421
PtexPlatform.h
Platform-specific classes, functions, and includes.
Ptex::MetaDataType
MetaDataType
Type of meta data entry.
Definition: Ptexture.h:107
Ptex::OneValue
static float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0. ...
Definition: Ptexture.h:138
PtexUtils::VecAccumN
Definition: PtexUtils.h:172
Ptex::MeshTypeName
static const char * MeshTypeName(MeshType mt)
Look up name of given mesh type.
Definition: PtexUtils.cpp:45
PtexUtils::applyConstFunctions
static ApplyConstFn applyConstFunctions[20]
Definition: PtexUtils.h:203
Ptex::BorderMode
BorderMode
How to handle mesh border when filtering.
Definition: Ptexture.h:91
Ptex::Res::vlog2
int8_t vlog2
log base 2 of v resolution, in texels
Definition: Ptexture.h:163
PtexUtils::clamp
static T clamp(T x, T lo, T hi)
Definition: PtexUtils.h:122
PtexUtils::genRfaceids
static void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
Definition: PtexUtils.cpp:613
Ptex::dt_float
Single-precision (32-bit) floating point.
Definition: Ptexture.h:87
operator<<
std::ostream & operator<<(std::ostream &stream, const Ptex::String &str)
Definition: PtexUtils.cpp:673
PtexHalf
Half-precision (16-bit) floating-point type.
Definition: PtexHalf.h:84
Ptex::DataTypeName
static const char * DataTypeName(DataType dt)
Look up name of given data type.
Definition: PtexUtils.cpp:54
Ptex::MeshType
MeshType
Type of base mesh for which the textures are defined.
Definition: Ptexture.h:77
PtexUtils::fill
static void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
Definition: PtexUtils.cpp:405
PtexUtils::encodeDifference
static void encodeDifference(void *data, int size, DataType dt)
Definition: PtexUtils.cpp:233
PtexUtils::VecAccum
Definition: PtexUtils.h:158
Ptex::MetaDataTypeName
static const char * MetaDataTypeName(MetaDataType mdt)
Look up name of given meta data type.
Definition: PtexUtils.cpp:81
Ptex::Res::ulog2
int8_t ulog2
log base 2 of u resolution, in texels
Definition: Ptexture.h:162
Ptex::BorderModeName
static const char * BorderModeName(BorderMode m)
Look up name of given border mode.
Definition: PtexUtils.cpp:63
PtexUtils::divalpha
static void divalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
Definition: PtexUtils.cpp:601
PtexUtils::deinterleave
static void deinterleave(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:208
PtexUtils
Definition: PtexUtils.h:41
PtexUtils::reduceu
static void reduceu(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:316
PtexUtils::interleave
static void interleave(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:171
PtexUtils::reducev
static void reducev(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:349
Ptex::FaceInfo::res
Res res
Resolution of face.
Definition: Ptexture.h:238
Ptex::FaceInfo
Information about a face, as stored in the Ptex file header.
Definition: Ptexture.h:237
PtexHalf.h
Half-precision floating-point type.
PtexUtils::decodeDifference
static void decodeDifference(void *data, int size, DataType dt)
Definition: PtexUtils.cpp:253
Ptex::ConvertToFloat
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.
Definition: PtexUtils.cpp:107
PtexUtils::reduce
static void reduce(const void *src, int sstride, int ures, int vres, void *dst, int dstride, DataType dt, int nchannels)
Definition: PtexUtils.cpp:282
PtexUtils.h
Ptex::ConvertFromFloat
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.
Definition: PtexUtils.cpp:118
Ptex::String::c_str
const char * c_str() const
Definition: Ptexture.h:312
PtexUtils::isConstant
static bool isConstant(const void *data, int stride, int ures, int vres, int pixelSize)
Definition: PtexUtils.cpp:129
Ptex::EdgeIdName
static const char * EdgeIdName(EdgeId eid)
Look up name of given edge ID.
Definition: PtexUtils.cpp:72
Ptex::EdgeId
EdgeId
Edge IDs used in adjacency data in the Ptex::FaceInfo struct.
Definition: Ptexture.h:99