0001:
0002:
0003:
0004:
0005:
0006:
0007: #define STRICT
0008: #include <stdio.h>
0009: #include "hdr.h"
0010:
0011:
0012:
0013: namespace HDR{
0014:
0015: #define COLXS 128
0016: #define MAXGSHIFT 31
0017: static BYTE *g_mant = NULL, *g_nexp = NULL;
0018: static BYTE (*g_bval)[256] = NULL;
0019:
0020:
0021:
0022:
0023:
0024: typedef BYTE COLR[4];
0025: #define RED 0
0026: #define GRN 1
0027: #define BLU 2
0028: #define EXP 3
0029:
0030:
0031:
0032:
0033:
0034: typedef struct{
0035: char mn[64];
0036: char fs[64];
0037: double xp;
0038: int x;
0039: int y;
0040: unsigned char or;
0041: int sl;
0042: int ns;
0043: }Info;
0044:
0045:
0046: #define XDECR 1
0047: #define YDECR 2
0048: #define YMAJOR 4
0049:
0050: #define MINELEN 8
0051: #define MAXELEN 0x7fff
0052:
0053:
0054: #define PIXSTANDARD (YMAJOR|YDECR)
0055: #define PIXSTDFMT "-Y %d +X %d\n"
0056:
0057:
0058:
0059:
0060:
0061:
0062:
0063:
0064: void s_RemoveCRCF(char *p)
0065: {
0066: int len;
0067:
0068: for(len = strlen(p)-1; 0<=len; len--)
0069: {
0070: if( p[len]!='\r' && p[len]!='\n' ) break;
0071: p[len] = '\0';
0072: }
0073: }
0074:
0075:
0076:
0077:
0078:
0079:
0080:
0081: void s_ValData(Info *r, const char *s)
0082: {
0083: if(0 == strncmp(s, "#?", 2))
0084: {
0085: strcat(r->mn, s+2);
0086: s_RemoveCRCF(r->mn);
0087: }
0088: else if(0 == strncmp(s, "FORMAT=", 7))
0089: {
0090: strcat(r->fs, s+7);
0091: s_RemoveCRCF(r->fs);
0092: }
0093: }
0094:
0095:
0096:
0097:
0098:
0099:
0100: int s_GetHeader(FILE *fp, Info *cp)
0101: {
0102: const int MAXLINE = 512;
0103: char buf[MAXLINE];
0104:
0105: for ( ; ; ) {
0106: buf[MAXLINE-2] = '\n';
0107: if (fgets(buf, MAXLINE, fp) == NULL) return(-1);
0108:
0109: if (buf[0] == '\n') return(0);
0110: if (buf[0] == '\r' && buf[1] == '\n') return(0);
0111:
0112: if (buf[MAXLINE-2] != '\n') {
0113:
0114: buf[MAXLINE-2] = '\0';
0115: }
0116: s_ValData(cp, buf);
0117: }
0118: }
0119:
0120:
0121:
0122:
0123:
0124:
0125:
0126:
0127: int s_Str2Resolu( Info *r, const char *s )
0128: {
0129: const char *xndx = NULL;
0130: const char *yndx = NULL;
0131: const char *cp;
0132:
0133: if (s == NULL) return(0);
0134:
0135:
0136: for (cp = s; *cp; cp++){
0137: if (*cp == 'X'){
0138: xndx = cp;
0139: }else if (*cp == 'Y'){
0140: yndx = cp;
0141: }
0142: }
0143:
0144:
0145: if (xndx == NULL || yndx == NULL) return(0);
0146:
0147:
0148: r->or = 0;
0149: if (xndx > yndx) r->or |= YMAJOR;
0150: if (xndx[-1] == '-') r->or |= XDECR;
0151: if (yndx[-1] == '-') r->or |= YDECR;
0152:
0153:
0154: if ((r->x = atoi(xndx+1)) <= 0) return(0);
0155: if ((r->y = atoi(yndx+1)) <= 0) return(0);
0156:
0157: return(1);
0158: }
0159:
0160:
0161:
0162:
0163:
0164:
0165:
0166:
0167: int s_GetResolution(FILE *fp, Info *cp)
0168: {
0169: const int MAXLINE = 512;
0170: char buf[MAXLINE];
0171:
0172: buf[MAXLINE-2] = '\n';
0173: if (fgets(buf, MAXLINE, fp) == NULL) return(-1);
0174:
0175: s_Str2Resolu(cp, buf);
0176:
0177: return (0);
0178: }
0179:
0180:
0181:
0182:
0183:
0184:
0185:
0186:
0187: int s_GetResolu(Info *p)
0188: {
0189: if (p->or & YMAJOR) {
0190: p->sl = p->x;
0191: p->ns = p->y;
0192: } else {
0193: p->sl = p->y;
0194: p->ns = p->x;
0195: }
0196:
0197: return(0);
0198: }
0199:
0200:
0201:
0202:
0203:
0204:
0205:
0206: int s_CheckHeader(FILE *fin, Info *pInfo)
0207: {
0208:
0209: pInfo->mn[0] = '\0';
0210: pInfo->fs[0] = '\0';
0211: pInfo->xp = 1.0000000000000;
0212: pInfo->x = 0;
0213: pInfo->y = 0;
0214: pInfo->or = 0;
0215: pInfo->sl = 0;
0216: pInfo->ns = 0;
0217:
0218:
0219: if (s_GetHeader(fin, pInfo) < 0) return(-1);
0220:
0221:
0222: if (pInfo->mn[0]=='\0' || strcmp("RADIANCE", pInfo->mn) ) return -1;
0223:
0224:
0225: if (pInfo->fs[0]=='\0' || strcmp("32-bit_rle_rgbe", pInfo->fs) ) return -1;
0226:
0227:
0228: if (s_GetResolution(fin, pInfo) < 0) return(-1);
0229: if (pInfo->x <= 0 || pInfo->y <= 0) return -1;
0230: s_GetResolu(pInfo);
0231:
0232:
0233: return 1;
0234: }
0235:
0236:
0237:
0238:
0239:
0240:
0241:
0242:
0243: int s_OldReadColors(COLR *scanline, int len, FILE *fp)
0244: {
0245: int rshift;
0246: register int i;
0247:
0248: rshift = 0;
0249:
0250: while (0 < len) {
0251: scanline[0][RED] = getc(fp);
0252: scanline[0][GRN] = getc(fp);
0253: scanline[0][BLU] = getc(fp);
0254: scanline[0][EXP] = getc(fp);
0255:
0256: if (feof(fp) || ferror(fp)) return(-1);
0257:
0258: if (scanline[0][RED] == 1 &&
0259: scanline[0][GRN] == 1 &&
0260: scanline[0][BLU] == 1)
0261: {
0262:
0263:
0264: for (i = scanline[0][EXP] << rshift; i > 0; i--) {
0265: scanline[0][0]=scanline[-1][0];
0266: scanline[0][1]=scanline[-1][1];
0267: scanline[0][2]=scanline[-1][2];
0268: scanline[0][3]=scanline[-1][3];
0269: scanline++;
0270: len--;
0271: }
0272: rshift += 8;
0273: } else {
0274: scanline++;
0275: len--;
0276: rshift = 0;
0277: }
0278: }
0279: return(0);
0280: }
0281:
0282:
0283:
0284:
0285:
0286:
0287:
0288:
0289: int s_ReadColor (COLR *scanline, int len, FILE *fp)
0290: {
0291: int i, j;
0292: int code, val;
0293:
0294:
0295:
0296:
0297:
0298: if (len < MINELEN || MAXELEN < len ){
0299:
0300: return(s_OldReadColors(scanline, len, fp));
0301: }
0302:
0303: i = getc(fp);
0304: if (i == EOF) return(-1);
0305:
0306: if (i != 2) {
0307:
0308: ungetc(i, fp);
0309: return(s_OldReadColors(scanline, len, fp));
0310: }
0311:
0312: scanline[0][GRN] = getc(fp);
0313: scanline[0][BLU] = getc(fp);
0314: if ((i = getc(fp)) == EOF) return(-1);
0315:
0316:
0317:
0318: if (scanline[0][GRN] != 2 || scanline[0][BLU] & 128) {
0319: scanline[0][RED] = 2;
0320: scanline[0][EXP] = i;
0321: return(s_OldReadColors(scanline+1, len-1, fp));
0322: }
0323:
0324:
0325: if ((scanline[0][BLU]<<8 | i) != len) return(-1);
0326:
0327:
0328: for (i = 0; i < 4; i++)
0329: {
0330: for (j = 0; j < len; )
0331: {
0332:
0333: if ((code = getc(fp)) == EOF) return(-1);
0334:
0335: if (128 < code) {
0336:
0337: code &= 127;
0338: val = getc(fp);
0339: while (code--) scanline[j++][i] = val;
0340: } else {
0341:
0342: while (code--) scanline[j++][i] = getc(fp);
0343: }
0344: }
0345: }
0346:
0347:
0348: return(feof(fp) ? -1 : 0);
0349: }
0350:
0351:
0352:
0353:
0354:
0355:
0356:
0357:
0358: int Ra2Skel(FILE *fp, int sl, int nl, LPCTSTR *pErr, LPDIRECT3DTEXTURE9 pTexture)
0359: {
0360: int ret=0;
0361: COLR *scanin;
0362: register int x;
0363: int y;
0364:
0365:
0366: if ((scanin = (COLR *) malloc(sl*sizeof(COLR))) == NULL)
0367: {
0368: static LPCTSTR ErrMsg = "Out of memory.";
0369: if(pErr) *pErr = ErrMsg;
0370: return -1;
0371: }
0372:
0373:
0374: D3DLOCKED_RECT d3dlr;
0375: if(FAILED(pTexture->LockRect(0, &d3dlr, NULL, 0)))
0376: {
0377: static LPCTSTR ErrMsg = "error to lock texture.";
0378: if(pErr) *pErr = ErrMsg;
0379: ret = -1;
0380: goto err1_end;
0381: }
0382:
0383:
0384: BYTE* pDstRow = (BYTE*)d3dlr.pBits;
0385: for (y = nl-1; y >= 0; y--) {
0386: if (s_ReadColor(scanin, sl, fp) < 0)
0387: {
0388: static LPCTSTR ErrMsg = "error reading Radiance picture.";
0389: if(pErr) *pErr = ErrMsg;
0390: ret = -1;
0391: goto err2_end;
0392: }
0393:
0394: BYTE* pDst = pDstRow;
0395: for (x = 0; x < sl; x++) {
0396: pDst[0] = scanin[x][BLU];
0397: pDst[1] = scanin[x][GRN];
0398: pDst[2] = scanin[x][RED];
0399: pDst[3] = scanin[x][EXP];
0400: pDst += 4;
0401: }
0402: pDstRow += d3dlr.Pitch;
0403: }
0404: err2_end:
0405:
0406: pTexture->UnlockRect(0);
0407:
0408: err1_end:
0409:
0410:
0411: free((char *)scanin);
0412:
0413: return ret;
0414: }
0415:
0416:
0417:
0418:
0419:
0420:
0421:
0422:
0423: HRESULT CreateTextureFromFile(
0424: LPDIRECT3DDEVICE9 pDevice,
0425: LPCTSTR pSrcFile,
0426: LPCTSTR *pErr,
0427: LPDIRECT3DTEXTURE9 *pTexture)
0428: {
0429: HRESULT hr = S_OK;
0430: Info info;
0431:
0432: FILE *fd;
0433:
0434: if( (fd = fopen( pSrcFile,"rb" )) == NULL )
0435: {
0436: static LPCTSTR ErrMsg = "Can't open input file.";
0437: if(pErr) *pErr = ErrMsg;
0438: hr = -1;
0439: return -1;
0440: }
0441:
0442:
0443: if (s_CheckHeader(fd, &info) < 0)
0444: {
0445: static LPCTSTR ErrMsg = "Bad picture format.";
0446: if(pErr) *pErr = ErrMsg;
0447: hr = -1;
0448: goto err_data;
0449: }
0450:
0451:
0452: if(FAILED(hr=D3DXCreateTexture(pDevice, info.x, info.y
0453: , 1, 0, D3DFMT_A8R8G8B8
0454: , D3DPOOL_MANAGED, pTexture)))
0455: {
0456: static LPCTSTR ErrMsg = "Failed to create texture.";
0457: if(pErr) *pErr = ErrMsg;
0458: goto err_data;
0459: }
0460:
0461:
0462: if( Ra2Skel(fd, info.sl, info.ns, pErr, *pTexture) < 0)
0463: {
0464: hr = -1;
0465: }
0466:
0467: err_data:
0468:
0469: fclose( fd );
0470:
0471: return hr;
0472: }
0473:
0474: }
0475:
0476:
0477: