static void hdr_read_uncompressed(float* out, unsigned char* in, unsigned int width, unsigned int height) { unsigned int num_pixels = width * height; while(num_pixels-- > 0) { rgbe2float(&out[0],&out[1], &out[2], in); in += 4; out += 3; } }
/* simple read routine. will not correctly handle run length encoding */ static int rgbe_read_pixels(struct img_io *io, float *data, int numpixels) { unsigned char rgbe[4]; while(numpixels-- > 0) { if(io->read(rgbe, sizeof(rgbe), io->uptr) < 1) return rgbe_error(rgbe_read_error, NULL); rgbe2float(&data[RGBE_DATA_RED], &data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE], rgbe); data += RGBE_DATA_SIZE; } return RGBE_RETURN_SUCCESS; }
/* simple read routine. will not correctly handle run length encoding */ int RGBE_ReadPixels(FILE *fp, float *data, int numpixels) { unsigned char rgbe[4]; while(numpixels-- > 0) { if (fread(rgbe, sizeof(rgbe), 1, fp) < 1) return rgbe_error(rgbe_read_error,NULL); rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE],rgbe); data += RGBE_DATA_SIZE; } return RGBE_RETURN_SUCCESS; }
int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width, int num_scanlines) { unsigned char rgbe[4], *scanline_buffer, *ptr, *ptr_end; int i, count; unsigned char buf[2]; if ((scanline_width < 8)||(scanline_width > 0x7fff)) /* run length encoding is not allowed so read flat*/ return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines); scanline_buffer = NULL; /* read in each successive scanline */ while(num_scanlines > 0) { if (fread(rgbe,sizeof(rgbe),1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL); } if ((rgbe[0] != 2)||(rgbe[1] != 2)||(rgbe[2] & 0x80)) { /* this file is not run length encoded */ rgbe2float(&data[0],&data[1],&data[2],rgbe); data += RGBE_DATA_SIZE; free(scanline_buffer); return RGBE_ReadPixels(fp,data,scanline_width*num_scanlines-1); } if ((((int)rgbe[2])<<8 | rgbe[3]) != scanline_width) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"wrong scanline width"); } if (scanline_buffer == NULL) scanline_buffer = (unsigned char *) malloc(sizeof(unsigned char)*4*scanline_width); if (scanline_buffer == NULL) return rgbe_error(rgbe_memory_error,"unable to allocate buffer space"); ptr = &scanline_buffer[0]; /* read each of the four channels for the scanline into the buffer */ for(i=0; i<4; i++) { ptr_end = &scanline_buffer[(i+1)*scanline_width]; while(ptr < ptr_end) { if (fread(buf,sizeof(buf[0])*2,1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL); } if (buf[0] > 128) { /* a run of the same value */ count = buf[0]-128; if ((count == 0)||(count > ptr_end - ptr)) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"bad scanline data"); } while(count-- > 0) *ptr++ = buf[1]; } else { /* a non-run */ count = buf[0]; if ((count == 0)||(count > ptr_end - ptr)) { free(scanline_buffer); return rgbe_error(rgbe_format_error,"bad scanline data"); } *ptr++ = buf[1]; if (--count > 0) { if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) { free(scanline_buffer); return rgbe_error(rgbe_read_error,NULL); } ptr += count; } } } } /* now convert data from buffer into floats */ for(i=0; i<scanline_width; i++) { rgbe[0] = scanline_buffer[i]; rgbe[1] = scanline_buffer[i+scanline_width]; rgbe[2] = scanline_buffer[i+2*scanline_width]; rgbe[3] = scanline_buffer[i+3*scanline_width]; rgbe2float(&data[RGBE_DATA_RED],&data[RGBE_DATA_GREEN], &data[RGBE_DATA_BLUE],rgbe); data += RGBE_DATA_SIZE; } num_scanlines--; } free(scanline_buffer); return RGBE_RETURN_SUCCESS; }
void HDRtexture::load(const char *filename) { if(m_data) delete[] m_data; FILE *fp = fopen(filename, "rb"); if (!fp) { printf("Failed to load HDR image: %s\n", filename); return; } char sbuf[128]; float tempf; fgets(sbuf,sizeof(sbuf),fp); if(strcmp(sbuf,"#?RADIANCE\n")!=0) { printf("%s is not an HDR Image\n", filename); fclose(fp); return; } while(strcmp(sbuf,"\n")!=0) { if(strcmp(sbuf,"FORMAT=32-bit_rle_rgbe\n") == 0) m_format = RGBE_RLE_32BIT; else if(sscanf(sbuf,"EXPOSURE=%g",&tempf) == 1) {/*m_exposure = tempf;*/} fgets(sbuf,sizeof(sbuf),fp); } fgets(sbuf,sizeof(sbuf),fp); //printf(sbuf); if (sscanf(sbuf,"-Y %d +X %d",&m_height,&m_width) == 2) m_flip_vertical = 1; else if(sscanf(sbuf,"+Y %d +X %d",&m_height,&m_width) == 2) m_flip_vertical = 0; //if(m_width>=1024) m_width = 1024; //else m_width = 512; m_height = m_width/2; unsigned char* data = new unsigned char[m_width*m_height*4]; for(int j = 0; j<m_height; j++) { for(int i=0; i<m_width; i++) { data[(j*m_width+i)*4]=255; data[(j*m_width+i)*4+1]=255; data[(j*m_width+i)*4+2]=255; data[(j*m_width+i)*4+3]=255; } } unsigned char rgbe[4]; unsigned char buf[2]; int count; int line = m_height; while(line>0) { if(fread(rgbe,sizeof(rgbe),1,fp) < 1) { delete[] data; printf("Failed to read pixels\n"); return; } //printf("%i %i %i %i\n", rgbe[0], rgbe[1], rgbe[2], rgbe[3]); unsigned char* scanline_buf = new unsigned char[m_width*4]; unsigned char* ptr = &scanline_buf[0]; unsigned char* ptr_end; for(int i=0;i<4;i++) { ptr_end = &scanline_buf[(i+1)*m_width]; while(ptr<ptr_end) { fread(buf,2,1,fp); if(buf[0]>128) { count = buf[0]-128; while(count-- > 0) *ptr++ = buf[1]; } else { count = buf[0]; *ptr++ = buf[1]; if (--count > 0) { if (fread(ptr,sizeof(*ptr)*count,1,fp) < 1) { return; } ptr += count; } } } } for(int i=0;i<m_width;i++) { data[((line-1)*m_width+i)*4] = scanline_buf[i]; data[((line-1)*m_width+i)*4+1] = scanline_buf[i+m_width]; data[((line-1)*m_width+i)*4+2] = scanline_buf[i+2*m_width]; data[((line-1)*m_width+i)*4+3] = scanline_buf[i+3*m_width]; } line--; } fclose(fp); //for(int i=0; i<m_width*m_height; i=i+1024) m_data = new float[m_width*m_height*4]; //unsigned char rgbe[4]; for(int j=0; j<m_height; j++) { for(int i=0; i<m_width; i++) { rgbe[0] = data[(j*m_width+i)*4]; rgbe[1] = data[(j*m_width+i)*4+1]; rgbe[2] = data[(j*m_width+i)*4+2]; rgbe[3] = data[(j*m_width+i)*4+3]; rgbe2float(&m_data[(j*m_width+i)*4], &m_data[(j*m_width+i)*4+1], &m_data[(j*m_width+i)*4+2], rgbe); m_data[(j*m_width+i)*4+3] = 1.0f; } } //clean up delete[] data; m_valid = true; }
static void hdr_read_rle(float* out, unsigned char* in, unsigned int width, unsigned int height) { /* Read in each successive scanline */ unsigned char* scanline_buffer = 0; while (height > 0) { /* Read next 4 bytes into memory buffer */ unsigned char rgbe[4]; memcpy(rgbe, in, sizeof(rgbe)); in += sizeof(rgbe); if ((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) { /* This file is not run length encoded */ rgbe2float(&out[0], &out[1], &out[2], rgbe); out += 3; free(scanline_buffer); hdr_read_uncompressed(out, in, width, height - 1); return; } if ((((int)rgbe[2]) << 8 | rgbe[3]) != (int)width) { free(scanline_buffer); assert(0 && "wrong scanline width"); } if (scanline_buffer == 0) scanline_buffer = malloc(width * 4); /* Read each of the four channels for the scanline into the buffer */ unsigned char* ptr = &scanline_buffer[0]; for (unsigned int i = 0; i < 4; ++i) { unsigned char* ptr_end = &scanline_buffer[(i + 1) * width]; while (ptr < ptr_end) { unsigned char buf[2]; memcpy(buf, in, sizeof(buf)); in += sizeof(buf); if (buf[0] > 128) { /* A run of the same value */ int count = buf[0] - 128; if ((count == 0) || (count > ptr_end - ptr)) { free(scanline_buffer); assert(0 && "bad scanline data"); } while (count-- > 0) *ptr++ = buf[1]; } else { /* A non-run */ int count = buf[0]; if ((count == 0) || (count > ptr_end - ptr)) { free(scanline_buffer); assert(0 && "bad scanline data"); } *ptr++ = buf[1]; if (--count > 0) { memcpy(ptr, in, count); in += count; ptr += count; } } } } /* Now convert data from buffer into floats */ for (unsigned int i = 0; i < width; ++i) { rgbe[0] = scanline_buffer[i]; rgbe[1] = scanline_buffer[i + width]; rgbe[2] = scanline_buffer[i + 2 * width]; rgbe[3] = scanline_buffer[i + 3 * width]; rgbe2float(&out[0], &out[1], &out[2], rgbe); out += 3; } height--; } free(scanline_buffer); }