VideoCodec/Modules/Output/FrameOutputModule.cpp
#include "FrameOutputModule.h"
#include "../../Logger.h"
namespace VideoCodec
{
FrameOutputModule::~FrameOutputModule()
{
// The file output prefix will be deleted in the configuration destructor.
}
ConfigurationStatus FrameOutputModule::Configure(ConfigurationElement* configuration)
{
this->caching = (configuration != NULL && configuration->GetValue("caching") != NULL && configuration->GetValue("caching")->GetType() == CONFIGURATION_STRING && *configuration->GetValue("caching")->GetString() == "true");
if (configuration != NULL && configuration->GetValue("prefix") != NULL && configuration->GetValue("prefix")->GetType() == CONFIGURATION_STRING)
{
std::string* value = configuration->GetValue("prefix")->GetString();
this->fileOutputPrefix = value;
}
else
this->fileOutputPrefix = new string("frame");
return MODULE_CONFIGURATION_OK;
}
// Writes the image represented by the specified pixel data to a file. The file name
// is the prefix specified during configuration with the index of the image
// appended to it.
void FrameOutputModule::WriteImage(PictureInfo* picture, int imageIndex)
{
char* fileName = new char[255];
sprintf(fileName, "%s%04d.png", this->fileOutputPrefix->c_str(), imageIndex);
this->WriteImage(picture, std::string(fileName));
delete fileName;
}
void FrameOutputModule::FlushCachedImages()
{
// If caching is off, there's nothing to do.
if (!this->caching)
return;
// Disable caching and flush the images to disk.
this->caching = false;
for (map<std::string, PictureInfo*>::iterator i = this->cachedPictures.begin(); i != this->cachedPictures.end(); i++)
{
this->WriteImage(i->second, i->first);
delete i->second;
}
}
// Write the image to the specified file name.
void FrameOutputModule::WriteImage(PictureInfo* picture, std::string name)
{
// Show a warning if the pixels are not in RGB format.
if (picture->GetColourFormat() != COLOUR_FORMAT_RGB)
Logger::LogMessage("Warning: Frame output requires RGB colour format.");
if (this->caching)
{
// Store a clone of the picture data to be output later.
this->cachedPictures[name] = picture->Clone();
return;
}
PixelCount pixelsX = picture->GetPixelsX();
PixelCount pixelsY = picture->GetPixelsY();
UnsignedByte* components = picture->GetUnsignedByteData();
Magick::Image outputImage(Magick::Geometry(pixelsX, pixelsY), "white");
outputImage.type(Magick::TrueColorType);
outputImage.modifyImage();
Magick::Pixels view(outputImage);
// Move the pixel pointer over the image, setting values.
Magick::PixelPacket* pixels = view.get(0, 0, pixelsX, pixelsY);
for (int y = 0, index = 0, componentIndex = 0; y < pixelsY; y++)
for (int x = 0; x < pixelsX; x++, index++, componentIndex += 3)
pixels[index] = Magick::ColorRGB((double)components[componentIndex] / 255.0,
(double)components[componentIndex + 1] / 255.0,
(double)components[componentIndex + 2] / 255.0);
// Store the pixels in the image.
view.sync();
// Save to a file with the current frame number.
outputImage.write(name);
}
}