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);    } }