Exemplo n.º 1
0
void WriteHdrImage(const std::string outName, const int width, const int height, Color* image) {
	// Turn image from a 2D-bottom-up array of Vector3D to an top-down-array of floats
	float* data = new float[width*height * 3];
	float* dp = data;
	for (int y = height - 1; y >= 0; --y) {
		for (int x = 0; x<width; ++x) {
			Color pixel = image[y*width + x];
			*dp++ = pixel[0];
			*dp++ = pixel[1];
			*dp++ = pixel[2];
		}
	}

	// Write image to file in HDR (a.k.a RADIANCE) format
	rgbe_header_info info;
	char errbuf[100] = { 0 };

	FILE* fp = fopen(outName.c_str(), "wb");
	info.valid = false;
	int r = RGBE_WriteHeader(fp, width, height, &info, errbuf);
	if (r != RGBE_RETURN_SUCCESS)
		printf("error: %s\n", errbuf);

	r = RGBE_WritePixels_RLE(fp, data, width, height, errbuf);
	if (r != RGBE_RETURN_SUCCESS)
		printf("error: %s\n", errbuf);
	fclose(fp);

	delete data;
}
Exemplo n.º 2
0
bool writeHDR(const char* path, const cv::Mat& hdr)
{
  FILE* fp = std::fopen(path, "wb");
  if (fp == NULL) {
    std::fprintf(stderr, "cannot write to %s\n", path);
    return false;
  }
  
  cv::Size size = hdr.size();
  cv::Mat tmp = hdr.clone();
  for (int y = 0; y < size.height; ++y) {
    for (int x = 0; x < size.width; ++x) {
      cv::Vec3f& c = tmp.at<cv::Vec3f>(y, x);
      std::swap(c[0], c[2]);
    }
  }
  float* data = (float*)((void*)(tmp.ptr()));
  RGBE_WriteHeader(fp, size.width, size.height, NULL);
  RGBE_WritePixels_RLE(fp, data, size.width, size.height);
  
  std::fclose(fp);
  return true;
}
Exemplo n.º 3
0
OIIO_PLUGIN_EXPORTS_END


bool
HdrOutput::open (const std::string &name, const ImageSpec &newspec,
                 OpenMode mode)
{
    if (mode != Create) {
        error ("%s does not support subimages or MIP levels", format_name());
        return false;
    }

    // Save spec for later use
    m_spec = newspec;
    // HDR always behaves like floating point
    m_spec.set_format (TypeDesc::FLOAT);

    // Check for things HDR can't support
    if (m_spec.nchannels != 3) {
        error ("HDR can only support 3-channel images");
        return false;
    }
    if (m_spec.width < 1 || m_spec.height < 1) {
        error ("Image resolution must be at least 1x1, you asked for %d x %d",
               m_spec.width, m_spec.height);
        return false;
    }
    if (m_spec.depth < 1)
        m_spec.depth = 1;
    if (m_spec.depth > 1) {
        error ("%s does not support volume images (depth > 1)", format_name());
        return false;
    }

    m_spec.set_format (TypeDesc::FLOAT);   // Native rgbe is float32 only

    m_fd = Filesystem::fopen (name, "wb");
    if (m_fd == NULL) {
        error ("Unable to open file");
        return false;
    }

    rgbe_header_info h;
    h.valid = 0;

    // Most readers seem to think that rgbe files are valid only if they
    // identify themselves as from "RADIANCE".
    h.valid |= RGBE_VALID_PROGRAMTYPE;
    Strutil::safe_strcpy (h.programtype, "RADIANCE", sizeof(h.programtype));

    ParamValue *p;
    p = m_spec.find_attribute ("Orientation", TypeDesc::INT);
    if (p) {
        h.valid |= RGBE_VALID_ORIENTATION;
        h.orientation = * (int *)p->data();
    }

    // FIXME -- should we do anything about gamma, exposure, software,
    // pixaspect, primaries?  (N.B. rgbe.c doesn't even handle most of them)

    int r = RGBE_WriteHeader (m_fd, m_spec.width, m_spec.height, &h, rgbe_error);
    if (r != RGBE_RETURN_SUCCESS)
        error ("%s", rgbe_error);

    // If user asked for tiles -- which this format doesn't support, emulate
    // it by buffering the whole image.
    if (m_spec.tile_width && m_spec.tile_height)
        m_tilebuffer.resize (m_spec.image_bytes());

    return true;
}
Exemplo n.º 4
0
// Internal function used to save the Hdr.
ILboolean iSaveHdrInternal()
{
	ILimage *TempImage;
	rgbe_header_info stHeader;
	unsigned char rgbe[4];
	ILubyte		*buffer;
	ILfloat		*data;
	ILuint		i;
	ILboolean	bRet;

	if (iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	stHeader.exposure = 0;
	stHeader.gamma = 0;
	stHeader.programtype[0] = 0;
	stHeader.valid = 0;

	if (iCurImage->Format != IL_UNSIGNED_BYTE) {
		TempImage = iConvertImage(iCurImage, IL_RGB, IL_FLOAT);
		if (TempImage == NULL)
			return IL_FALSE;
	}
	else
		TempImage = iCurImage;

	if (!RGBE_WriteHeader(TempImage->Width, TempImage->Height, &stHeader))
		return IL_FALSE;

	if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT)
		iFlipBuffer(TempImage->Data,TempImage->Depth,TempImage->Bps,TempImage->Height);
	data = (ILfloat*)TempImage->Data;


	if ((TempImage->Width < 8)||(TempImage->Width > 0x7fff)) {
		/* run length encoding is not allowed so write flat*/
		bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height);
		if (iCurImage != TempImage)
			ilCloseImage(TempImage);
		return bRet;
	}
	buffer = (ILubyte*)ialloc(sizeof(ILubyte)*4*TempImage->Width);
	if (buffer == NULL) {
		/* no buffer space so write flat */
		bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height);
		if (iCurImage != TempImage)
			ilCloseImage(TempImage);
		return bRet;
	}

	while(TempImage->Height-- > 0) {
		rgbe[0] = 2;
		rgbe[1] = 2;
		rgbe[2] = TempImage->Width >> 8;
		rgbe[3] = TempImage->Width & 0xFF;
		if (iwrite(rgbe, sizeof(rgbe), 1) < 1) {
			free(buffer);
			if (iCurImage != TempImage)
				ilCloseImage(TempImage);
			return IL_FALSE;
		}

		for(i=0;i<TempImage->Width;i++) {
			float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
			buffer[i] = rgbe[0];
			buffer[i+TempImage->Width] = rgbe[1];
			buffer[i+2*TempImage->Width] = rgbe[2];
			buffer[i+3*TempImage->Width] = rgbe[3];
			data += RGBE_DATA_SIZE;
		}
		/* write out each of the four channels separately run length encoded */
		/* first red, then green, then blue, then exponent */
		for(i=0;i<4;i++) {
			if (RGBE_WriteBytes_RLE(&buffer[i*TempImage->Width],TempImage->Width) != IL_TRUE) {
				ifree(buffer);
				if (iCurImage != TempImage)
					ilCloseImage(TempImage);
				return IL_FALSE;
			}
		}
	}
	ifree(buffer);

	if (iCurImage != TempImage)
		ilCloseImage(TempImage);
	return IL_TRUE;
}