00001
00002 #include <cstring>
00003 #include <textures/imagetex.h>
00004 #include <core_api/environment.h>
00005
00006 __BEGIN_YAFRAY
00007
00008 #define MINELEN 8
00009 #define MAXELEN 0x7fff
00010 #define MINRUN 4 // minimum run length
00011 #define RED 0
00012 #define GRN 1
00013 #define BLU 2
00014 #define EXP 3
00015 #define COLXS 128
00016
00017 RGBEtexture_t::RGBEtexture_t(gBuf_t<rgbe_t, 1> *im, textureImage_t::INTERPOLATE_TYPE intp, double exposure):
00018 textureImage_t(intp), image(im), EXPadjust(1.f)
00019 {
00020 if(exposure != 0.0f) setExposureAdjust(exposure);
00021 }
00022
00023 RGBEtexture_t::~RGBEtexture_t()
00024 {
00025 if(image) delete image;
00026 image = 0;
00027 }
00028
00029 bool checkHDR(FILE *file, int &xmax, int &ymax)
00030 {
00031 char cs[256], st1[80], st2[80];
00032 bool resok = false, HDRok = false;
00033 while (!feof(file) && !HDRok)
00034 {
00035 fgets(cs, 255, file);
00036 if (strstr(cs, "32-bit_rle_rgbe")){ HDRok = true; break; }
00037 }
00038 if(!HDRok) return false;
00039 while (!feof(file) && !resok)
00040 {
00041 fgets(cs, 255, file);
00042 if (strcmp(cs, "\n") == 0) {
00043
00044
00045 fgets(cs, 255, file);
00046 sscanf(cs, "%s %d %s %d", (char*)&st1, &ymax, (char*)&st2, &xmax);
00047 resok = true;
00048 }
00049 }
00050 return (HDRok && resok);
00051 }
00052
00053
00054 bool oldreadcolrs(FILE *file, rgbe_t *scan, int xmax)
00055 {
00056 int i, rshift = 0, len = xmax;
00057 while (len > 0) {
00058 scan[0].rgbe[RED] = (unsigned char)getc(file);
00059 scan[0].rgbe[GRN] = (unsigned char)getc(file);
00060 scan[0].rgbe[BLU] = (unsigned char)getc(file);
00061 scan[0].rgbe[EXP] = (unsigned char)getc(file);
00062 if (feof(file) || ferror(file)) return false;
00063 if (scan[0].rgbe[RED] == 1 && scan[0].rgbe[GRN] == 1 && scan[0].rgbe[BLU] == 1) {
00064 for (i=scan[0].rgbe[EXP]<<rshift;i>0;i--) {
00065 scan[0] = scan[-1];
00066 scan++;
00067 len--;
00068 }
00069 rshift += 8;
00070 }
00071 else {
00072 scan++;
00073 len--;
00074 rshift = 0;
00075 }
00076 }
00077 return true;
00078 }
00079
00080
00081 bool freadcolrs(FILE *file, rgbe_t *scan, int xmax)
00082 {
00083 int i,j,code,val;
00084 if ((xmax < MINELEN) | (xmax > MAXELEN)) return oldreadcolrs(file, scan, xmax);
00085 if ((i = getc(file)) == EOF) return false;
00086 if (i != 2) {
00087 ungetc(i, file);
00088 return oldreadcolrs(file, scan, xmax);
00089 }
00090 scan[0].rgbe[GRN] = (unsigned char)getc(file);
00091 scan[0].rgbe[BLU] = (unsigned char)getc(file);
00092 if ((i = getc(file)) == EOF) return false;
00093 if (((scan[0].rgbe[BLU] << 8) | i) != xmax) return false;
00094 for (i=0;i<4;i++)
00095 for (j=0;j<xmax;) {
00096 if ((code = getc(file)) == EOF) return false;
00097 if (code > 128) {
00098 code &= 127;
00099 val = getc(file);
00100 while (code--)
00101 scan[j++].rgbe[i] = (unsigned char)val;
00102 }
00103 else
00104 while (code--)
00105 scan[j++].rgbe[i] = (unsigned char)getc(file);
00106 }
00107 return feof(file) ? false : true;
00108 }
00109
00110 gBuf_t<rgbe_t, 1>* loadHDR(const char* filename)
00111 {
00112 FILE *file = fopen(filename,"rb");
00113 int xmax, ymax;
00114 if (file==NULL) return false;
00115 if (!checkHDR(file, xmax, ymax)) {
00116 fclose(file);
00117 return false;
00118 }
00119 bool ok=true;
00120 gBuf_t<rgbe_t, 1> *image = new gBuf_t<rgbe_t, 1>(xmax, ymax);
00121 rgbe_t *scanline = new rgbe_t[xmax];
00122 for (int y=ymax-1;y>=0;y--) {
00123 if( freadcolrs(file, scanline, xmax) )
00124 {
00125 for(int x=0; x<xmax; ++x) *(*image)(x, y) = scanline[x];
00126 }
00127 else
00128 {
00129 delete image; delete[] scanline; ok = false; break;
00130 }
00131 }
00132 fclose(file);
00133 delete[] scanline;
00134 return ok ? image : 0;
00135 }
00136
00137 void RGBEtexture_t::resolution(int &x, int &y, int &z) const
00138 {
00139 if(image){ x=image->resx(); y=image->resy(); z=0; }
00140 else { x=0; y=0; z=0; }
00141 }
00142
00143 static inline void getRgbePixel(rgbe_t *data, colorA_t &col){ col = color_t(*data); }
00144
00145 colorA_t RGBEtexture_t::getColor(const point3d_t &p) const
00146 {
00147 point3d_t p1 = p;
00148 bool outside = doMapping(p1);
00149 if(outside) return colorA_t(0.f, 0.f, 0.f, 0.f);
00150
00151 if(!image) return color_t(0.0);
00152 colorA_t expad(EXPadjust,EXPadjust,EXPadjust,1.f);
00153 return expad * interpolateImage(image, intp_type, p1, getRgbePixel);
00154
00155 }
00156
00157 colorA_t RGBEtexture_t::getColor(int x, int y, int z) const
00158 {
00159 int resx, resy;
00160 if(image) resx=image->resx(), resy=image->resy();
00161 else return colorA_t(0.f);
00162 x = (x<0) ? 0 : ((x>=resx) ? resx-1 : x);
00163 y = (y<0) ? 0 : ((y>=resy) ? resy-1 : y);
00164 colorA_t c1;
00165 getRgbePixel( (*image)(x, y), c1);
00166 return c1;
00167 }
00168
00169 CFLOAT RGBEtexture_t::getFloat(const point3d_t &p) const
00170 {
00171 return getColor(p).energy();
00172 }
00173
00174 __END_YAFRAY