1 #ifndef Ptexture_h
2 #define Ptexture_h
3 
4 /*
5 PTEX SOFTWARE
6 Copyright 2014 Disney Enterprises, Inc.  All rights reserved
7 
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are
10 met:
11 
12   * Redistributions of source code must retain the above copyright
13     notice, this list of conditions and the following disclaimer.
14 
15   * Redistributions in binary form must reproduce the above copyright
16     notice, this list of conditions and the following disclaimer in
17     the documentation and/or other materials provided with the
18     distribution.
19 
20   * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
21     Studios" or the names of its contributors may NOT be used to
22     endorse or promote products derived from this software without
23     specific prior written permission from Walt Disney Pictures.
24 
25 Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
26 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
28 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
29 IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
30 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37 */
38 
39 /**
40   @file Ptexture.h
41   @brief Public API classes for reading, writing, caching, and filtering Ptex files.
42 */
43 
44 #if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER)
45 # ifndef PTEXAPI
46 #  ifndef PTEX_STATIC
47 #    ifdef PTEX_EXPORTS
48 #       define PTEXAPI __declspec(dllexport)
49 #    else
50 #       define PTEXAPI __declspec(dllimport)
51 #    endif
52 #  else
53 #    define PTEXAPI
54 #  endif
55 # endif
56 #else
57 #  ifndef PTEXAPI
58 #    define PTEXAPI
59 #  endif
60 #  ifndef DOXYGEN
61 #    define PTEX_USE_STDSTRING
62 #  endif
63 #endif
64 
65 #include "PtexInt.h"
66 #include <ostream>
67 
68 #include "PtexVersion.h"
69 #ifdef DOXYGEN
70 /** Common data structures and enums used throughout the API */
71 namespace Ptex {
72 #else
73 PTEX_NAMESPACE_BEGIN
74 #endif
75 
76  /** Type of base mesh for which the textures are defined.  A mesh
77      can be triangle-based (with triangular textures) or quad-based
78      (with rectangular textures). */
79 enum MeshType {
80      mt_triangle,		///< Mesh is triangle-based.
81      mt_quad			///< Mesh is quad-based.
82  };
83 
84 /** Type of data stored in texture file. */
85 enum DataType {
86     dt_uint8,		///< Unsigned, 8-bit integer.
87     dt_uint16,		///< Unsigned, 16-bit integer.
88     dt_half,		///< Half-precision (16-bit) floating point.
89     dt_float		///< Single-precision (32-bit) floating point.
90 };
91 
92 /** How to handle transformation across edges when filtering */
93 enum EdgeFilterMode {
94     efm_none,		///< Don't do anything with the values.
95     efm_tanvec		///< Values are vectors in tangent space; rotate values.
96 };
97 
98 /** How to handle mesh border when filtering. */
99 enum BorderMode {
100     m_clamp,		///< texel access is clamped to border
101     m_black,		///< texel beyond border are assumed to be black
102     m_periodic		///< texel access wraps to other side of face
103 };
104 
105 /** Edge IDs used in adjacency data in the Ptex::FaceInfo struct.
106     Edge ID usage for triangle meshes is TBD. */
107 enum EdgeId {
108     e_bottom,		///< Bottom edge, from UV (0,0) to (1,0)
109     e_right,		///< Right edge, from UV (1,0) to (1,1)
110     e_top,			///< Top edge, from UV (1,1) to (0,1)
111     e_left			///< Left edge, from UV (0,1) to (0,0)
112 };
113 
114 /** Type of meta data entry. */
115 enum MetaDataType {
116     mdt_string,		///< Null-terminated string.
117     mdt_int8,		///< Signed 8-bit integer.
118     mdt_int16,		///< Signed 16-bit integer.
119     mdt_int32,		///< Signed 32-bit integer.
120     mdt_float,		///< Single-precision (32-bit) floating point.
121     mdt_double		///< Double-precision (32-bit) floating point.
122 };
123 
124 /** Look up name of given mesh type. */
125 PTEXAPI const char* MeshTypeName(MeshType mt);
126 
127 /** Look up name of given data type. */
128 PTEXAPI const char* DataTypeName(DataType dt);
129 
130 /** Look up name of given border mode. */
131 PTEXAPI const char* BorderModeName(BorderMode m);
132 
133 /** Look up name of given edge filter mode. */
134 PTEXAPI const char* EdgeFilterModeName(EdgeFilterMode m);
135 
136 /** Look up name of given edge ID. */
137 PTEXAPI const char* EdgeIdName(EdgeId eid);
138 
139 /** Look up name of given meta data type. */
140 PTEXAPI const char* MetaDataTypeName(MetaDataType mdt);
141 
142 /** Look up size of given data type (in bytes). */
DataSize(DataType dt)143 inline int DataSize(DataType dt) {
144     static const int sizes[] = { 1,2,2,4 };
145     return sizes[dt];
146 }
147 
148 /** Look up value of given data type that corresponds to the normalized value of 1.0. */
OneValue(DataType dt)149 inline float OneValue(DataType dt) {
150     static const float one[] = { 255.f, 65535.f, 1.f, 1.f };
151     return one[dt];
152 }
153 
154 /** Lookup up inverse value of given data type that corresponds to the normalized value of 1.0. */
OneValueInv(DataType dt)155 inline float OneValueInv(DataType dt) {
156     static const float one[] = { 1.f/255.f, 1.f/65535.f, 1.f, 1.f };
157     return one[dt];
158 }
159 
160 /** Convert a number of data values from the given data type to float. */
161 PTEXAPI void ConvertToFloat(float* dst, const void* src,
162                             Ptex::DataType dt, int numChannels);
163 
164 /** Convert a number of data values from float to the given data type. */
165 PTEXAPI void ConvertFromFloat(void* dst, const float* src,
166                               Ptex::DataType dt, int numChannels);
167 
168 /** Pixel resolution of a given texture.
169     The resolution is stored in log form: ulog2 = log2(ures), vlog2 = log2(vres)).
170     Note: negative ulog2 or vlog2 values are reserved for internal use.
171 */
172 struct Res {
173     int8_t ulog2;		///< log base 2 of u resolution, in texels
174     int8_t vlog2;		///< log base 2 of v resolution, in texels
175 
176     /// Default constructor, sets res to 0 (1x1 texel).
ResRes177     Res() : ulog2(0), vlog2(0) {}
178 
179     /// Constructor.
ResRes180     Res(int8_t ulog2_, int8_t vlog2_) : ulog2(ulog2_), vlog2(vlog2_) {}
181 
182     /// Constructor.
ResRes183     Res(uint16_t value) : ulog2(int8_t(value&0xff)), vlog2(int8_t((value>>8)&0xff)) {}
184 
185     /// U resolution in texels.
uRes186     int u() const { return 1<<(unsigned)ulog2; }
187 
188     /// V resolution in texels.
vRes189     int v() const { return 1<<(unsigned)vlog2; }
190 
191     /// Resolution as a single 16-bit integer value.
valRes192     uint16_t val() const { return uint16_t(ulog2 | (vlog2<<8)); }
193 
194     /// Total size of specified texture in texels (u * v).
sizeRes195     int size() const { return u() * v(); }
196 
197     /// Comparison operator.
198     bool operator==(const Res& r) const { return r.ulog2 == ulog2 && r.vlog2 == vlog2; }
199 
200     /// Comparison operator.
201     bool operator!=(const Res& r) const { return !(r==*this); }
202 
203     /// True if res is >= given res in both u and v directions.
204     bool operator>=(const Res& r) const { return ulog2 >= r.ulog2 && vlog2 >= r.vlog2; }
205 
206     /// Get value of resolution with u and v swapped.
swappeduvRes207     Res swappeduv() const { return Res(vlog2, ulog2); }
208 
209     /// Swap the u and v resolution values in place.
swapuvRes210     void swapuv() { *this = swappeduv(); }
211 
212     /// Clamp the resolution value against the given value.
clampRes213     void clamp(const Res& r) {
214         if (ulog2 > r.ulog2) ulog2 = r.ulog2;
215         if (vlog2 > r.vlog2) vlog2 = r.vlog2;
216     }
217 
218     /// Determine the number of tiles in the u direction for the given tile res.
ntilesuRes219     int ntilesu(Res tileres) const { return 1<<(ulog2-tileres.ulog2); }
220 
221     /// Determine the number of tiles in the v direction for the given tile res.
ntilesvRes222     int ntilesv(Res tileres) const { return 1<<(vlog2-tileres.vlog2); }
223 
224     /// Determine the total number of tiles for the given tile res.
ntilesRes225     int ntiles(Res tileres) const { return ntilesu(tileres) * ntilesv(tileres); }
226 };
227 
228 /** Information about a face, as stored in the Ptex file header.
229     The FaceInfo data contains the face resolution and neighboring face
230     adjacency information as well as a set of flags describing the face.
231 
232     The adjfaces data member contains the face ids of the four neighboring faces.
233     The neighbors are accessed in EdgeId order, CCW, starting with the bottom edge.
234     The adjedges data member contains the corresponding edge id for each neighboring face.
235 
236     If a face has no neighbor for a given edge, the adjface id should be -1, and the
237     adjedge id doesn't matter (but is typically zero).
238 
239     If an adjacent face is a pair of subfaces, the id of the first subface as encountered
240     in a CCW traversal should be stored as the adjface id.
241 */
242 struct FaceInfo {
243     Res res;		///< Resolution of face.
244     uint8_t adjedges;       ///< Adjacent edges, 2 bits per edge.
245     uint8_t flags;		///< Flags.
246     int32_t adjfaces[4];	///< Adjacent faces (-1 == no adjacent face).
247 
248     /// Default constructor
FaceInfoFaceInfo249     FaceInfo() : res(), adjedges(0), flags(0)
250     {
251         adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1;
252     }
253 
254     /// Constructor.
FaceInfoFaceInfo255     FaceInfo(Res res_) : res(res_), adjedges(0), flags(0)
256     {
257         adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1;
258     }
259 
260     /// Constructor.
261     FaceInfo(Res res_, int adjfaces_[4], int adjedges_[4], bool isSubface_=false)
resFaceInfo262         : res(res_), flags(isSubface_ ? flag_subface : 0)
263     {
264         setadjfaces(adjfaces_[0], adjfaces_[1], adjfaces_[2], adjfaces_[3]);
265         setadjedges(adjedges_[0], adjedges_[1], adjedges_[2], adjedges_[3]);
266     }
267 
268     /// Access an adjacent edge id.  The eid value must be 0..3.
adjedgeFaceInfo269     EdgeId adjedge(int eid) const { return EdgeId((adjedges >> (2*eid)) & 3); }
270 
271     /// Access an adjacent face id.  The eid value must be 0..3.
adjfaceFaceInfo272     int adjface(int eid) const { return adjfaces[eid]; }
273 
274     /// Determine if face is constant (by checking a flag).
isConstantFaceInfo275     bool isConstant() const { return (flags & flag_constant) != 0; }
276 
277     /// Determine if neighborhood of face is constant (by checking a flag).
isNeighborhoodConstantFaceInfo278     bool isNeighborhoodConstant() const { return (flags & flag_nbconstant) != 0; }
279 
280     /// Determine if face has edits in the file (by checking a flag).
hasEditsFaceInfo281     bool hasEdits() const { return (flags & flag_hasedits) != 0; }
282 
283     /// Determine if face is a subface (by checking a flag).
isSubfaceFaceInfo284     bool isSubface() const { return (flags & flag_subface) != 0; }
285 
286     /// Set the adjfaces data.
setadjfacesFaceInfo287     void setadjfaces(int f0, int f1, int f2, int f3)
288     { adjfaces[0] = f0, adjfaces[1] = f1, adjfaces[2] = f2; adjfaces[3] = f3; }
289 
290     /// Set the adjedges data.
setadjedgesFaceInfo291     void setadjedges(int e0, int e1, int e2, int e3)
292     { adjedges = (uint8_t)((e0&3) | ((e1&3)<<2) | ((e2&3)<<4) | ((e3&3)<<6)); }
293 
294     /// Flag bit values (for internal use).
295     enum { flag_constant = 1, flag_hasedits = 2, flag_nbconstant = 4, flag_subface = 8 };
296 };
297 
298 
299 /** Memory-managed string. Used for returning error messages from
300     API functions.  On most platforms, this is a typedef to
301     std::string.  For Windows, this is a custom class that
302     implements a subset of std::string.  (Note: std::string cannot
303     be passed through a Windows DLL interface).
304 */
305 #ifdef PTEX_USE_STDSTRING
306 typedef std::string String;
307 #else
308 class String
309 {
310 public:
String()311     String() : _str(0) {}
String(const String & str)312     String(const String& str) : _str(0) { *this = str; }
313     PTEXAPI ~String();
314     PTEXAPI String& operator=(const char* str);
315     String& operator=(const String& str) { *this = str._str; return *this; }
316     String& operator=(const std::string& str) { *this = str.c_str(); return *this; }
c_str()317     const char* c_str() const { return _str ? _str : ""; }
empty()318     bool empty() const { return _str == 0 || _str[0] == '\0'; }
319 
320 private:
321     char* _str;
322 };
323 #endif
324 
325 /// std::stream output operator.  \relates Ptex::String
326 #ifndef PTEX_USE_STDSTRING
327 std::ostream& operator << (std::ostream& stream, const Ptex::String& str);
328 #endif
329 
330 
331 #ifdef DOXYGEN
332 } // end namespace Ptex
333 #endif
334 
335 /**
336    @class PtexMetaData
337    @brief Meta data accessor
338 
339    Meta data is acquired from PtexTexture and accessed through this interface.
340  */
341 class PtexMetaData {
342  protected:
343     /// Destructor not for public use.  Use release() instead.
~PtexMetaData()344     virtual ~PtexMetaData() {}
345 
346  public:
347     /// Release resources held by this pointer (pointer becomes invalid).
348     virtual void release() = 0;
349 
350     /// Query number of meta data entries stored in file.
351     virtual int numKeys() = 0;
352 
353     /// Query the name and type of a meta data entry.
354     virtual void getKey(int index, const char*& key, Ptex::MetaDataType& type) = 0;
355 
356     /// Query the index and type of a meta data entry by name.
357     virtual bool findKey(const char* key, int& index, Ptex::MetaDataType& type) = 0;
358 
359     /** Query the value of a given meta data entry.
360 	If the key doesn't exist or the type doesn't match, value is set to null */
361     virtual void getValue(const char* key, const char*& value) = 0;
362 
363     /** Query the value of a given meta data entry by index.
364 	If the index is out of range or the type doesn't match, value is set to null */
365     virtual void getValue(int index, const char*& value) = 0;
366 
367     /** Query the value of a given meta data entry.
368 	If the key doesn't exist or the type doesn't match, value is set to null */
369     virtual void getValue(const char* key, const int8_t*& value, int& count) = 0;
370 
371     /** Query the value of a given meta data entry by index.
372 	If the index is out of range or the type doesn't match, value is set to null */
373     virtual void getValue(int index, const int8_t*& value, int& count) = 0;
374 
375     /** Query the value of a given meta data entry.
376 	If the key doesn't exist or the type doesn't match, value is set to null */
377     virtual void getValue(const char* key, const int16_t*& value, int& count) = 0;
378 
379     /** Query the value of a given meta data entry by index.
380 	If the index is out of range or the type doesn't match, value is set to null */
381     virtual void getValue(int index, const int16_t*& value, int& count) = 0;
382 
383     /** Query the value of a given meta data entry.
384 	If the key doesn't exist or the type doesn't match, value is set to null */
385     virtual void getValue(const char* key, const int32_t*& value, int& count) = 0;
386 
387     /** Query the value of a given meta data entry by index.
388 	If the index is out of range or the type doesn't match, value is set to null */
389     virtual void getValue(int index, const int32_t*& value, int& count) = 0;
390 
391     /** Query the value of a given meta data entry.
392 	If the key doesn't exist or the type doesn't match, value is set to null */
393     virtual void getValue(const char* key, const float*& value, int& count) = 0;
394 
395     /** Query the value of a given meta data entry by index.
396 	If the index is out of range or the type doesn't match, value is set to null */
397     virtual void getValue(int index, const float*& value, int& count) = 0;
398 
399     /** Query the value of a given meta data entry.
400 	If the key doesn't exist or the type doesn't match, value is set to null */
401     virtual void getValue(const char* key, const double*& value, int& count) = 0;
402 
403     /** Query the value of a given meta data entry by index.
404 	If the index is out of range or the type doesn't match, value is set to null */
405     virtual void getValue(int index, const double*& value, int& count) = 0;
406 };
407 
408 
409 /**
410     @class PtexFaceData
411     @brief Per-face texture data accessor
412 
413     Per-face texture data is acquired from PtexTexture and accessed
414     through this interface.  This interface provides low-level access
415     to the data as stored on disk for maximum efficiency.  If this
416     isn't needed, face data can be more conveniently read directly
417     from PtexTexture.
418  */
419 class PtexFaceData {
420  protected:
421     /// Destructor not for public use.  Use release() instead.
~PtexFaceData()422     virtual ~PtexFaceData() {}
423 
424  public:
425     /// Release resources held by this pointer (pointer becomes invalid).
426     virtual void release() = 0;
427 
428     /** True if this data block is constant. */
429     virtual bool isConstant() = 0;
430 
431     /** Resolution of the texture held by this data block.  Note: the
432         indicated texture res may be larger than 1x1 even if the
433         texture data is constant. */
434     virtual Ptex::Res res() = 0;
435 
436     /** Read a single texel from the data block.  The texel coordinates, u and v, have
437         a range of [0..ures-1, 0..vres-1].  Note: this method will work correctly even if
438         the face is constant or tiled. */
439     virtual void getPixel(int u, int v, void* result) = 0;
440 
441     /** Access the data from this data block.
442 
443         If the data block is constant, getData will return a pointer to a single texel's data value.
444 
445         If the data block is tiled, then getData will return null and
446         the data must be accessed per-tile via the getTile() function. */
447     virtual void* getData() = 0;
448 
449     /** True if this data block is tiled.
450         If tiled, the data must be access per-tile via getTile(). */
451     virtual bool isTiled() = 0;
452 
453     /** Resolution of each tile in this data block. */
454     virtual Ptex::Res tileRes() = 0;
455 
456     /** Access a tile from the data block.  Tiles are accessed in v-major order. */
457     virtual PtexFaceData* getTile(int tile) = 0;
458 };
459 
460 
461 /**
462    @class PtexTexture
463    @brief Interface for reading data from a ptex file
464 
465    PtexTexture instances can be acquired via the static open() method, or via
466    the PtexCache interface.
467 
468    Data access through this interface is returned in v-major order with all data channels interleaved per texel.
469  */
470 class PtexTexture {
471  protected:
472     /// Destructor not for public use.  Use release() instead.
~PtexTexture()473     virtual ~PtexTexture() {}
474 
475  public:
476     /** Open a ptex file for reading.
477 
478         If an error occurs, an error message will be stored in the
479         error string param and a null pointer will be returned.
480 
481         If the premultiply param is set to true and the texture file has a specified alpha channel,
482         then all data stored in the file will be multiplied by alpha when read from disk.  If premultiply
483         is false, then the full-resolution textures will be returned as stored on disk which is assumed
484         to be unmultiplied.  Reductions (both stored mip-maps and dynamically generated reductions) are
485         always premultiplied with alpha.  See PtexWriter for more information about alpha channels.
486     */
487     PTEXAPI static PtexTexture* open(const char* path, Ptex::String& error, bool premultiply=0);
488 
489 
490     /// Release resources held by this pointer (pointer becomes invalid).
491     virtual void release() = 0;
492 
493     /** Path that file was opened with.  If the file was opened using a search path (via PtexCache),
494         the the path will be the path as found in the search path.  Otherwise, the path will be
495         the path as supplied to open. */
496     virtual const char* path() = 0;
497 
498     /** Get most commonly used info in a single call for convenience / efficiency */
499     struct Info {
500         MeshType meshType;
501         DataType dataType;
502         BorderMode uBorderMode;
503         BorderMode vBorderMode;
504         EdgeFilterMode edgeFilterMode;
505         int alphaChannel;
506         int numChannels;
507         int numFaces;
508     };
509     virtual Info getInfo() = 0;
510 
511     /** Type of mesh for which texture data is defined. */
512     virtual Ptex::MeshType meshType() = 0;
513 
514     /** Type of data stored in file. */
515     virtual Ptex::DataType dataType() = 0;
516 
517     /** Mode for filtering texture access beyond mesh border. */
518     virtual Ptex::BorderMode uBorderMode() = 0;
519 
520     /** Mode for filtering texture access beyond mesh border. */
521     virtual Ptex::BorderMode vBorderMode() = 0;
522 
523     /** Mode for filtering textures across edges. */
524     virtual Ptex::EdgeFilterMode edgeFilterMode() = 0;
525 
526     /** Index of alpha channel (if any).  One channel in the file can be flagged to be the alpha channel.
527         If no channel is acting as the alpha channel, -1 is returned.
528         See PtexWriter for more details.  */
529     virtual int alphaChannel() = 0;
530 
531     /** Number of channels stored in file. */
532     virtual int numChannels() = 0;
533 
534     /** Number of faces stored in file. */
535     virtual int numFaces() = 0;
536 
537     /** True if the file has edit blocks.  See PtexWriter for more details. */
538     virtual bool hasEdits() = 0;
539 
540     /** True if the file has mipmaps.  See PtexWriter for more details. */
541     virtual bool hasMipMaps() = 0;
542 
543     /** Access meta data. */
544     virtual PtexMetaData* getMetaData() = 0;
545 
546     /** Access resolution and adjacency information about a face. */
547     virtual const Ptex::FaceInfo& getFaceInfo(int faceid) = 0;
548 
549     /** Access texture data for a face at highest-resolution.
550 
551         The texture data is copied into the user-supplied buffer.
552         The buffer must be at least this size (in bytes):
553         DataSize(dataType()) * numChannels() * getFaceInfo(faceid).res.size().
554 
555         If a stride is given, then (stride-row_length) bytes will be
556         skipped after each row.  If stride is zero, then no bytes will
557         be skipped.  Note: the image can be flipped vertically by using
558         an appropriate negative stride value.
559 
560         @param faceid Face index [0..numFaces-1]
561         @param buffer User-supplied buffer
562         @param stride Size of each row in user buffer (in bytes)
563     */
564     virtual void getData(int faceid, void* buffer, int stride) = 0;
565 
566     /** Access texture data for a face at a specific resolution.
567 
568         The specified resolution may be lower than the full resolution
569         for the face.  If it is lower, then the texture data is
570         accessed from the stored mip-maps.  If the requested
571         resolution doesn't match a stored resolution, the desired
572         resolution will be generated from the nearest available
573         resolution.
574 
575         See previous getData() method for interface details.
576      */
577     virtual void getData(int faceid, void* buffer, int stride, Ptex::Res res) = 0;
578 
579     /** Access texture data for a face at highest-resolution as stored on disk. */
580     virtual PtexFaceData* getData(int faceid) = 0;
581 
582     /** Access texture data for a face at a specific resolution as stored on disk.
583 
584         The specified resolution may be lower (but not higher) than
585         the full resolution for the face.  If it is lower, then the
586         texture data is accessed from the stored mip-maps.  If the
587         requested resolution doesn't match a stored resolution, the
588         desired resolution will be generated from the nearest
589         available resolution.
590       */
591     virtual PtexFaceData* getData(int faceid, Ptex::Res res) = 0;
592 
593     /** Access a single texel from the highest resolution texture .
594         The texel data is converted to floating point (integer types
595         are normalized 0.0 to 1.0).  A subset of the available
596         channels may be accessed.
597 
598         @param faceid Face index [0..numFaces-1]
599         @param u U coordinate [0..ures-1]
600         @param v V coordinate [0..vres-1]
601         @param result Result data
602         @param firstchan First channel to access [0..numChannels-1]
603         @param nchannels Number of channels to access.
604      */
605     virtual void getPixel(int faceid, int u, int v,
606                           float* result, int firstchan, int nchannels) = 0;
607 
608     /** Access a single texel for a face at a particular resolution.
609 
610         The specified resolution may be lower (but not higher) than
611         the full resolution for the face.  If it is lower, then the
612         texture data is accessed from the stored mip-maps.  If the
613         requested resolution doesn't match a stored resolution, the
614         desired resolution will be generated from the nearest
615         available resolution.
616 
617         See previous getPixel() method for details.
618     */
619     virtual void getPixel(int faceid, int u, int v,
620                           float* result, int firstchan, int nchannels,
621                           Ptex::Res res) = 0;
622 };
623 
624 
625 /** @class PtexInputHandler
626     @brief Custom handler interface for intercepting and redirecting Ptex input stream calls
627 
628     A custom instance of this class can be defined and supplied to the PtexCache class.
629     Files accessed through the cache will have their input streams redirected through this
630     interface.
631  */
632 class PtexInputHandler {
633  protected:
~PtexInputHandler()634     virtual ~PtexInputHandler() {}
635 
636  public:
637     typedef void* Handle;
638 
639     /** Open a file in read mode.
640         Returns null if there was an error.
641         If an error occurs, the error string is available via lastError().
642     */
643     virtual Handle open(const char* path) = 0;
644 
645     /** Seek to an absolute byte position in the input stream. */
646     virtual void seek(Handle handle, int64_t pos) = 0;
647 
648     /** Read a number of bytes from the file.
649         Returns the number of bytes successfully read.
650         If less than the requested number of bytes is read, the error string
651         is available via lastError().
652     */
653     virtual size_t read(void* buffer, size_t size, Handle handle) = 0;
654 
655     /** Close a file.  Returns false if an error occurs, and the error
656         string is available via lastError().  */
657     virtual bool close(Handle handle) = 0;
658 
659     /** Return the last error message encountered. */
660     virtual const char* lastError() = 0;
661 };
662 
663 
664 /** @class PtexErrorHandler
665     @brief Custom handler interface redirecting Ptex error messages
666 
667     A custom instance of this class can be defined and supplied to the PtexCache class.
668     Files accessed through the cache will have their error streams redirected through this
669     interface.
670  */
671 class PtexErrorHandler {
672  protected:
~PtexErrorHandler()673     virtual ~PtexErrorHandler() {}
674 
675  public:
676     virtual void reportError(const char* error) = 0;
677 };
678 
679 
680 /**
681    @class PtexCache
682    @brief File-handle and memory cache for reading ptex files
683 
684    The PtexCache class allows cached read access to multiple ptex
685    files while constraining the open file count and memory usage to
686    specified limits.  File and data objects accessed via the cache
687    are added back to the cache when their release method is called.
688    Released objects are maintained in an LRU list and only destroyed
689    when the specified resource limits are exceeded.
690 
691    The cache is fully multi-threaded.  Cached data will be shared among
692    all threads that have access to the cache, and the data are protected
693    with internal locks.  See PtexCache.cpp for details about the caching
694    and locking implementation.
695  */
696 
697 class PtexCache {
698  protected:
699     /// Destructor not for public use.  Use release() instead.
~PtexCache()700     virtual ~PtexCache() {}
701 
702  public:
703     /** Create a cache with the specified limits.
704 
705         @param maxFiles Maximum open file handles.  If zero,
706         limit is set to 100 open files.
707 
708         @param maxMem Maximum allocated memory, in bytes.  If zero
709         the cache is unlimited.
710 
711         @param premultiply If true, textures will be premultiplied by
712         the alpha channel (if any) when read from disk.  For authoring
713         purposes, this should generally be set to false, and for
714         rendering purposes, this should generally be set to true.  See
715         PtexTexture and PtexWriter for more details.
716 
717         @param inputHandler If specified, all input calls made through this cache will
718         be directed through the handler.
719 
720         @param errorHandler If specified, errors encounted with files access through
721         this cache will be directed to the handler.  By default, errors will be
722         reported to stderr.
723      */
724     PTEXAPI static PtexCache* create(int maxFiles,
725                                      size_t maxMem,
726                                      bool premultiply=false,
727                                      PtexInputHandler* inputHandler=0,
728                                      PtexErrorHandler* errorHandler=0);
729 
730     /// Release PtexCache.  Cache will be immediately destroyed and all resources will be released.
731     virtual void release() = 0;
732 
733     /** Set a search path for finding textures.
734         Note: if an input handler is installed the search path will be ignored.
735 
736         @param path colon-delimited search path.
737      */
738     virtual void setSearchPath(const char* path) = 0;
739 
740     /** Query the search path.  Returns string set via setSearchPath.  */
741     virtual const char* getSearchPath() = 0;
742 
743     /** Access a texture.  If the specified path was previously accessed
744         from the cache, then a pointer to the cached texture will be
745         returned.
746 
747         If the specified path hasn't been opened yet or was purged
748         from the cache (via the purge or purgeAll methods) then the
749         file will be opened.  If the path is relative (i.e. doesn't
750         begin with a '/') then the search path will be used to locate
751         the file.
752 
753         The texture will be accessible until the PtexTexture::release
754         method is called, at which point the texture will be returned
755         to the cache.  Once released, the texture may have it's data
756         pruned (immediately or some time later) to stay within the
757         maximum cache size.
758 
759         If the texture could not be opened, null will be returned and
760         an error string will be set.  If an error were previously
761         encountered with the file (include the file not being found),
762         null will be returned and no error string will be set.
763 
764         @param path File path.  If path is relative, search path will
765         be used to find the file.
766 
767         @param error Error string set if texture could not be
768         opened.
769      */
770     virtual PtexTexture* get(const char* path, Ptex::String& error) = 0;
771 
772     /** Remove a texture file from the cache.  If the texture is in use
773         by another thread, that reference will remain valid and the file
774         will be purged once it is no longer in use.  This texture
775         should be released immediately after purging.
776      */
777     virtual void purge(PtexTexture* texture) = 0;
778 
779     /** Remove a texture file from the cache by pathname.  The path must
780         match the full path as opened.  This function will not search
781         for the file, but if a search path was used, the path must
782         match the path as found by the search path.
783      */
784     virtual void purge(const char* path) = 0;
785 
786     /** Remove all texture files from the cache. Textures with
787         active PtexTexture* handles will remain valid and will be purged
788         upon release.
789      */
790     virtual void purgeAll() = 0;
791 
792     struct Stats {
793         uint64_t memUsed;
794         uint64_t peakMemUsed;
795         uint64_t filesOpen;
796         uint64_t peakFilesOpen;
797         uint64_t filesAccessed;
798         uint64_t fileReopens;
799         uint64_t blockReads;
800     };
801 
802     /** Get stats. */
803     virtual void getStats(Stats& stats) = 0;
804 };
805 
806 
807 /**
808    @class PtexWriter
809    @brief Interface for writing data to a ptex file.
810 
811    Note: if an alpha channel is specified, then the textures being
812    written to the file are expected to have unmultiplied-alpha data.
813    Generated mipmaps will be premultiplied by the Ptex library.  On
814    read, PtexTexture will (if requested) premultiply all textures by
815    alpha when getData is called; by default only reductions are
816    premultiplied.  If the source textures are already premultiplied,
817    then alphachan can be set to -1 and the library will just leave all
818    the data as-is.  The only reason to store unmultiplied-alpha
819    textures in the file is to preserve the original texture data for
820    later editing.
821 */
822 
823 class PtexWriter {
824  protected:
825     /// Destructor not for public use.  Use release() instead.
~PtexWriter()826     virtual ~PtexWriter() {}
827 
828  public:
829     /** Open a new texture file for writing.
830         @param path Path to file.
831         @param mt Type of mesh for which the textures are defined.
832         @param dt Type of data stored within file.
833         @param nchannels Number of data channels.
834         @param alphachan Index of alpha channel, [0..nchannels-1] or -1 if no alpha channel is present.
835         @param nfaces Number of faces in mesh.
836         @param error String containing error message if open failed.
837         @param genmipmaps Specify true if mipmaps should be generated.
838      */
839     PTEXAPI
840     static PtexWriter* open(const char* path,
841                             Ptex::MeshType mt, Ptex::DataType dt,
842                             int nchannels, int alphachan, int nfaces,
843                             Ptex::String& error, bool genmipmaps=true);
844 
845     /** Open an existing texture file for writing.
846 
847         If the incremental param is specified as true, then data
848         values written to the file are appended to the file as "edit
849         blocks".  This is the fastest way to write data to the file, but
850         edit blocks are slower to read back, and they have no mipmaps so
851         filtering can be inefficient.
852 
853         If incremental is false, then the edits are applied to the
854         file and the entire file is regenerated on close as if it were
855         written all at once with open().
856 
857         If the file doesn't exist it will be created and written as if
858         open() were used.  If the file exists, the mesh type, data
859         type, number of channels, alpha channel, and number of faces
860         must agree with those stored in the file.
861      */
862     PTEXAPI
863     static PtexWriter* edit(const char* path, bool incremental,
864                             Ptex::MeshType mt, Ptex::DataType dt,
865                             int nchannels, int alphachan, int nfaces,
866                             Ptex::String& error, bool genmipmaps=true);
867 
868     /** Apply edits to a file.
869 
870         If a file has pending edits, the edits will be applied and the
871         file will be regenerated with no edits.  This is equivalent to
872         calling edit() with incremental set to false.  The advantage
873         is that the file attributes such as mesh type, data type,
874         etc., don't need to be known in advance.
875      */
876     PTEXAPI
877     static bool applyEdits(const char* path, Ptex::String& error);
878 
879     /** Release resources held by this pointer (pointer becomes invalid). */
880     virtual void release() = 0;
881 
882     /** Set border modes */
883     virtual void setBorderModes(Ptex::BorderMode uBorderMode, Ptex::BorderMode vBorderMode) = 0;
884 
885     /** Set edge filter mode */
886     virtual void setEdgeFilterMode(Ptex::EdgeFilterMode edgeFilterMode) = 0;
887 
888     /** Write a string as meta data.  Both the key and string params must be null-terminated strings. */
889     virtual void writeMeta(const char* key, const char* string) = 0;
890 
891     /** Write an array of signed 8-bit integers as meta data.  The key must be a null-terminated string. */
892     virtual void writeMeta(const char* key, const int8_t* value, int count) = 0;
893 
894     /** Write an array of signed 16-bit integers as meta data.  The key must be a null-terminated string. */
895     virtual void writeMeta(const char* key, const int16_t* value, int count) = 0;
896 
897     /** Write an array of signed 32-bit integers as meta data.  The key must be a null-terminated string. */
898     virtual void writeMeta(const char* key, const int32_t* value, int count) = 0;
899 
900     /** Write an array of signed 32-bit floats as meta data.  The key must be a null-terminated string. */
901     virtual void writeMeta(const char* key, const float* value, int count) = 0;
902 
903     /** Write an array of signed 32-bit doubles as meta data.  The key must be a null-terminated string. */
904     virtual void writeMeta(const char* key, const double* value, int count) = 0;
905 
906     /** Copy meta data from an existing meta data block. */
907     virtual void writeMeta(PtexMetaData* data) = 0;
908 
909     /** Write texture data for a face.
910         The data is assumed to be channel-interleaved per texel and stored in v-major order.
911 
912         @param faceid Face index [0..nfaces-1].
913         @param info Face resolution and adjacency information.
914         @param data Texel data.
915         @param stride Distance between rows, in bytes (if zero, data is assumed packed).
916 
917         If an error is encountered while writing, false is returned and an error message can be
918         retrieved when close is called.
919      */
920     virtual bool writeFace(int faceid, const Ptex::FaceInfo& info, const void* data, int stride=0) = 0;
921 
922     /** Write constant texture data for a face.
923         The data is written as a single constant texel value.  Note: the resolution specified in the
924         info param may indicate a resolution greater than 1x1 and the value will be preserved when
925         reading.  This is useful to indicate a texture's logical resolution even when the data is
926         constant. */
927     virtual bool writeConstantFace(int faceid, const Ptex::FaceInfo& info, const void* data) = 0;
928 
929     /** Close the file.  This operation can take some time if mipmaps are being generated or if there
930         are many edit blocks.  If an error occurs while writing, false is returned and an error string
931         is written into the error parameter. */
932     virtual bool close(Ptex::String& error) = 0;
933 
934 #if NEW_API
935     virtual bool writeFaceReduction(int faceid, const Ptex::Res& res, const void* data, int stride=0) = 0;
936     virtual bool writeConstantFaceReduction(int faceid, const Ptex::Res& res, const void* data) = 0;
937 #endif
938 };
939 
940 
941 /**
942    @class PtexFilter
943    @brief Interface for filtered sampling of ptex data files.
944 
945    PtexFilter instances are obtained by calling one of the particular static methods.  When finished using
946    the filter, it must be returned to the library using release().
947 
948    To apply the filter to a ptex data file, use the eval() method.
949  */
950 class PtexFilter {
951  protected:
952     /// Destructor not for public use.  Use release() instead.
~PtexFilter()953     virtual ~PtexFilter() {}
954 
955  public:
956     /// Filter types
957     enum FilterType {
958         f_point,                ///< Point-sampled (no filtering)
959         f_bilinear,             ///< Bi-linear interpolation
960         f_box,                  ///< Box filter
961         f_gaussian,             ///< Gaussian filter
962         f_bicubic,              ///< General bi-cubic filter (uses sharpness option)
963         f_bspline,              ///< BSpline (equivalent to bi-cubic w/ sharpness=0)
964         f_catmullrom,           ///< Catmull-Rom (equivalent to bi-cubic w/ sharpness=1)
965         f_mitchell              ///< Mitchell (equivalent to bi-cubic w/ sharpness=2/3)
966     };
967 
968     /// Choose filter options
969     struct Options {
970         int __structSize;       ///< (for internal use only)
971         FilterType filter;      ///< Filter type.
972         bool lerp;              ///< Interpolate between mipmap levels.
973         float sharpness;        ///< Filter sharpness, 0..1 (for general bi-cubic filter only).
974         bool noedgeblend;       ///< Disable cross-face filtering.  Useful for debugging or rendering on polys.
975 
976         /// Constructor - sets defaults
977         Options(FilterType filter_=f_box, bool lerp_=0, float sharpness_=0, bool noedgeblend_=0) :
__structSizeOptions978             __structSize(sizeof(Options)),
979             filter(filter_), lerp(lerp_), sharpness(sharpness_), noedgeblend(noedgeblend_) {}
980     };
981 
982     /* Construct a filter for the given texture.
983     */
984     PTEXAPI static PtexFilter* getFilter(PtexTexture* tx, const Options& opts);
985 
986     /** Release resources held by this pointer (pointer becomes invalid). */
987     virtual void release() = 0;
988 
989     /** Apply filter to a ptex data file.
990 
991         The filter region is a parallelogram centered at the given
992         (u,v) coordinate with sides defined by two vectors [uw1, vw1]
993         and [uw2, vw2].  For an axis-aligned rectangle, the vectors
994         are [uw, 0] and [0, vw].  See \link filterfootprint Filter
995         Footprint \endlink for details.
996 
997         @param result Buffer to hold filter result.  Must be large enough to hold nchannels worth of data.
998         @param firstchan First channel to evaluate [0..tx->numChannels()-1]
999         @param nchannels Number of channels to evaluate
1000         @param faceid Face index [0..tx->numFaces()-1]
1001         @param u U coordinate, normalized [0..1]
1002         @param v V coordinate, normalized [0..1]
1003         @param uw1 U filter width 1, normalized [0..1]
1004         @param vw1 V filter width 1, normalized [0..1]
1005         @param uw2 U filter width 2, normalized [0..1]
1006         @param vw2 V filter width 2, normalized [0..1]
1007         @param width scale factor for filter width
1008         @param blur amount to add to filter width [0..1]
1009     */
1010     virtual void eval(float* result, int firstchan, int nchannels,
1011                       int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2,
1012                       float width=1, float blur=0) = 0;
1013 };
1014 
1015 
1016 /**
1017    @class PtexPtr
1018    @brief Smart-pointer for acquiring and releasing API objects
1019 
1020    All public API objects must be released back to the Ptex library
1021    via the release() method.  This smart-pointer class can wrap any of
1022    the Ptex API objects and will automatically release the object when
1023    the pointer goes out of scope.  Usage of PtexPtr is optional, but
1024    recommended.
1025 
1026    Note: for efficiency and safety, PtexPtr is noncopyable.  However,
1027    ownership can be transferred between PtexPtr instances via the
1028    PtexPtr::swap member function.
1029 
1030    Example:
1031    \code
1032       {
1033           Ptex::String error;
1034           PtexPtr<PtexTexture> inptx(PtexTexture::open(inptxname, error));
1035           if (!inptx) {
1036               std::cerr << error << std::endl;
1037           }
1038           else {
1039               // read some data
1040               inptx->getData(faceid, buffer, stride);
1041           }
1042       }
1043    \endcode
1044  */
1045 template <class T> class PtexPtr {
1046     T* _ptr;
1047  public:
1048     /// Constructor.
_ptr(ptr)1049     PtexPtr(T* ptr=0) : _ptr(ptr) {}
1050 
1051     /// Destructor, calls ptr->release().
~PtexPtr()1052     ~PtexPtr() { if (_ptr) _ptr->release(); }
1053 
1054     /// Use as pointer value.
1055     operator T* () const { return _ptr; }
1056 
1057     /// Access members of pointer.
1058     T* operator-> () const { return _ptr; }
1059 
1060     /// Get pointer value.
get()1061     T* get() const { return _ptr; }
1062 
1063     /// Swap pointer values.
swap(PtexPtr & p)1064     void swap(PtexPtr& p)
1065     {
1066         T* tmp = p._ptr;
1067         p._ptr = _ptr;
1068         _ptr = tmp;
1069     }
1070 
1071     /// Deallocate object pointed to, and optionally set to new value.
1072     void reset(T* ptr=0) {
1073         if (_ptr) _ptr->release();
1074         _ptr = ptr;
1075     }
1076 
1077  private:
1078     /// Copying prohibited
1079     PtexPtr(const PtexPtr& p);
1080 
1081     /// Assignment prohibited
1082     void operator= (PtexPtr& p);
1083 };
1084 
1085 #ifndef DOXYGEN
1086 namespace PtexUtils {}
1087 
1088 PTEX_NAMESPACE_END
1089 
1090 using Ptex::PtexMetaData;
1091 using Ptex::PtexFaceData;
1092 using Ptex::PtexTexture;
1093 using Ptex::PtexInputHandler;
1094 using Ptex::PtexErrorHandler;
1095 using Ptex::PtexCache;
1096 using Ptex::PtexWriter;
1097 using Ptex::PtexFilter;
1098 using Ptex::PtexPtr;
1099 namespace PtexUtils = Ptex::PtexUtils;
1100 
1101 #endif
1102 #endif
1103