1 #include <string>
2 #include <map>
3 #include <iostream>
4 #include "Ptexture.h"
5 #include <cstdlib>
6 #include <cstdio> // printf()
7 using namespace Ptex;
8 
DumpData(Ptex::Res res,Ptex::DataType dt,int nchan,void * data,std::string prefix)9 void DumpData(Ptex::Res res, Ptex::DataType dt, int nchan, void* data, std::string prefix)
10 {
11     float* pixel = (float*) malloc(sizeof(float)*nchan);
12     uint8_t* cpixel = (uint8_t*) malloc(sizeof(uint8_t)*nchan);
13     printf("%sdata (%d x %d):\n", prefix.c_str(), res.u(), res.v());
14     int ures = res.u(), vres = res.v();
15     int pixelSize = Ptex::DataSize(dt) * nchan;
16 
17     for (int vi = 0; vi < vres; vi++) {
18         if (vi == 8 && vres > 16) { vi = vres-8; std::cout << prefix << "  ..." << std::endl; }
19         std::cout << prefix << "  ";
20         for (int ui = 0; ui < ures; ui++) {
21             if (ui == 8 && ures > 16) { ui = ures-8; std::cout << "... "; }
22             uint8_t* dpixel = (uint8_t*)data + (vi * ures + ui) * pixelSize;
23             Ptex::ConvertToFloat(pixel, dpixel, dt, nchan);
24             Ptex::ConvertFromFloat(cpixel, pixel, Ptex::dt_uint8, nchan);
25             for (int c=0; c < nchan; c++) {
26                 printf("%02x", cpixel[c]);
27             }
28             printf(" ");
29         }
30         printf("\n");
31     }
32 
33     free(cpixel);
34     free(pixel);
35 }
36 
37 template <typename T>
38 class DumpMetaArrayVal
39 {
40  public:
operator ()(PtexMetaData * meta,const char * key)41     void operator()(PtexMetaData* meta, const char* key)
42     {
43         const T* val=0;
44         int count=0;
45         meta->getValue(key, val, count);
46         for (int i = 0; i < count; i++) {
47             if (i%10==0 && (i || count > 10)) std::cout << "\n  ";
48             std::cout <<  "  " << val[i];
49         }
50     }
51 };
52 
53 
DumpMetaData(PtexMetaData * meta)54 void DumpMetaData(PtexMetaData* meta)
55 {
56     // Sort the meta keys before printing them out because the
57     // internal key order may change depending on whether large meta
58     // data support was included.  Normally the key order shouldn't
59     // matter, but we don't want it to cause the regression test to fail.
60 
61     std::map<std::string,int> sortedkeys;
62     for (int i = 0; i < meta->numKeys(); i++)
63     {
64         const char* key;
65         Ptex::MetaDataType type;
66         meta->getKey(i, key, type);
67         sortedkeys[key] = i;
68     }
69 
70     std::cout << "meta:" << std::endl;
71     std::map<std::string,int>::iterator iter;
72     for (iter = sortedkeys.begin(); iter != sortedkeys.end(); iter++) {
73         const char* key;
74         Ptex::MetaDataType type;
75         meta->getKey(iter->second, key, type);
76         std::cout << "  " << key << " type=" << Ptex::MetaDataTypeName(type);
77         switch (type) {
78         case Ptex::mdt_string:
79             {
80                 const char* val=0;
81                 meta->getValue(key, val);
82                 std::cout <<  "  " << val;
83             }
84             break;
85         case Ptex::mdt_int8:   DumpMetaArrayVal<int8_t>()(meta, key); break;
86         case Ptex::mdt_int16:  DumpMetaArrayVal<int16_t>()(meta, key); break;
87         case Ptex::mdt_int32:  DumpMetaArrayVal<int32_t>()(meta, key); break;
88         case Ptex::mdt_float:  DumpMetaArrayVal<float>()(meta, key); break;
89         case Ptex::mdt_double: DumpMetaArrayVal<double>()(meta, key); break;
90         }
91         std::cout << std::endl;
92     }
93 }
94 
main(int,char **)95 int main(int /*argc*/, char** /*argv*/)
96 {
97     Ptex::String error;
98     PtexPtr<PtexCache> c(PtexCache::create(0,0));
99     c->setSearchPath("foo/bar:.");
100     PtexPtr<PtexTexture> r(c->get("test.ptx", error));
101 
102     if (!r) {
103         std::cerr << error.c_str() << std::endl;
104         return 1;
105     }
106     std::cout << "meshType: " << Ptex::MeshTypeName(r->meshType()) << std::endl;
107     std::cout << "dataType: " << Ptex::DataTypeName(r->dataType()) << std::endl;
108     std::cout << "numChannels: " << r->numChannels() << std::endl;
109     std::cout << "alphaChannel: ";
110     if (r->alphaChannel() == -1) std::cout << "(none)" << std::endl;
111     else std::cout << r->alphaChannel() << std::endl;
112     std::cout << "numFaces: " << r->numFaces() << std::endl;
113 
114     PtexMetaData* meta = r->getMetaData();
115     std::cout << "numMetaKeys: " << meta->numKeys() << std::endl;
116     if (meta->numKeys()) DumpMetaData(meta);
117     meta->release();
118 
119     int nfaces = r->numFaces();
120     for (int i = 0; i < nfaces; i++) {
121         const Ptex::FaceInfo& f = r->getFaceInfo(i);
122         std::cout << "face " << i << ":\n"
123                   << "  res: " << int(f.res.ulog2) << ' ' << int(f.res.vlog2) << "\n"
124                   << "  adjface: "
125                   << f.adjfaces[0] << ' '
126                   << f.adjfaces[1] << ' '
127                   << f.adjfaces[2] << ' '
128                   << f.adjfaces[3] << "\n"
129                   << "  adjedge: "
130                   << f.adjedge(0) << ' '
131                   << f.adjedge(1) << ' '
132                   << f.adjedge(2) << ' '
133                   << f.adjedge(3) << "\n"
134                   << "  flags: " << int(f.flags) << "\n";
135 
136         Ptex::Res res = f.res;
137         void* data = malloc(Ptex::DataSize(r->dataType()) * r->numChannels() * res.size());
138         while (res.ulog2 > 0 || res.vlog2 > 0) {
139             r->getData(i, data, 0, res);
140             DumpData(res, r->dataType(), r->numChannels(), data, "  ");
141             if (res.ulog2) res.ulog2--;
142             if (res.vlog2) res.vlog2--;
143         }
144         r->getData(i, data, 0, Ptex::Res(0,0));
145         DumpData(res, r->dataType(), r->numChannels(), data, "  ");
146         free(data);
147 
148         // Read more channels than are available.
149         // This should wipe pixel with zeroes and nothing more.
150         float pixel[] = {-1.0f, -1.0f, -1.0f};
151         r->getPixel(i, 1, 1, pixel, 3, 3);
152         if (pixel[0] != 0.0f || pixel[1] != 0.0f || pixel[2] != 0.0f) {
153                 std::cerr << "pixel should be zero" << std::endl;
154                 return 1;
155         }
156     }
157 
158     return 0;
159 }
160