diff --git a/aegisub/src/video_provider_dummy.cpp b/aegisub/src/video_provider_dummy.cpp index f2531cf8e..d392a578c 100644 --- a/aegisub/src/video_provider_dummy.cpp +++ b/aegisub/src/video_provider_dummy.cpp @@ -36,183 +36,91 @@ #include "config.h" +#include "video_provider_dummy.h" + #ifndef AGI_PRE +#include #include #endif #include "colorspace.h" -#include "video_provider_dummy.h" -/// @brief Constructor -/// @param _fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// -void DummyVideoProvider::Create(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - lastFrame = -1; - framecount = frames; - fps = _fps; - width = _width; - height = _height; +void DummyVideoProvider::Create(double fps, int frames, int width, int height, unsigned char red, unsigned char green, unsigned char blue, bool pattern) { + this->framecount = frames; + this->fps = fps; + this->width = width; + this->height = height; + this->frame = AegiVideoFrame(width, height); - frame = AegiVideoFrame(width,height); unsigned char *dst = frame.data; - unsigned char r = colour.Red(), g = colour.Green(), b = colour.Blue(); - - unsigned char h, s, l, lr, lg, lb; // light variants - rgb_to_hsl(r, g, b, &h, &s, &l); - l += 24; - if (l < 24) l -= 48; - hsl_to_rgb(h, s, l, &lr, &lg, &lb); + unsigned char colors[2][4] = { + blue, green, red, 0, + 0, 0, 0, 0 + }; if (pattern) { + // Generate light version + unsigned char h, s, l; + rgb_to_hsl(red, blue, green, &h, &s, &l); + l += 24; + if (l < 24) l -= 48; + hsl_to_rgb(h, s, l, &colors[1][2], &colors[1][1], &colors[1][0]); + + // Divide into a 8x8 grid and use light colours when row % 2 != col % 2 int ppitch = frame.pitch / frame.GetBpp(); for (unsigned int y = 0; y < frame.h; ++y) { - if ((y / 8) & 1) { - for (int x = 0; x < ppitch; ++x) { - if ((x / 8) & 1) { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } - else { - *dst++ = lb; - *dst++ = lg; - *dst++ = lr; - *dst++ = 0; - } - } - } - else { - for (int x = 0; x < ppitch; ++x) { - if ((x / 8) & 1) { - *dst++ = lb; - *dst++ = lg; - *dst++ = lr; - *dst++ = 0; - } - else { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } - } + for (int x = 0; x < ppitch; ++x) { + memcpy(dst, colors[((y / 8) & 1) != ((x / 8) & 1)], 4); + dst += 4; } } } else { - for (int i=frame.pitch*frame.h/frame.GetBpp();--i>=0;) { - *dst++ = b; - *dst++ = g; - *dst++ = r; - *dst++ = 0; - } + for (int i = frame.pitch * frame.h / frame.GetBpp() - 1; i >= 0; --i) + memcpy(dst + i * 4, colors[0], 4); } } -/// @brief Parsing constructor -/// @param filename -/// -DummyVideoProvider::DummyVideoProvider(wxString filename) -{ +static long get_long(wxStringTokenizer &t, const char *err) { + long ret; + if (!t.GetNextToken().ToLong(&ret)) + throw VideoOpenError(err); + return ret; +} + +DummyVideoProvider::DummyVideoProvider(wxString const& filename) { wxString params; - if (!filename.StartsWith("?dummy:", ¶ms)) { + if (!filename.StartsWith("?dummy:", ¶ms)) throw agi::FileNotFoundError("Attempted creating dummy video provider with non-dummy filename"); - } wxStringTokenizer t(params, ":"); - if (t.CountTokens() < 7) { + if (t.CountTokens() < 7) throw VideoOpenError("Too few fields in dummy video parameter list"); - } double fps; - long _frames, _width, _height, red, green, blue; - bool pattern = false; - - wxString field = t.GetNextToken(); - if (!field.ToDouble(&fps)) { + if (!t.GetNextToken().ToDouble(&fps)) throw VideoOpenError("Unable to parse fps field in dummy video parameter list"); - } - field = t.GetNextToken(); - if (!field.ToLong(&_frames)) { - throw VideoOpenError("Unable to parse framecount field in dummy video parameter list"); - } + long frames = get_long(t, "Unable to parse framecount field in dummy video parameter list"); + long width = get_long(t, "Unable to parse width field in dummy video parameter list"); + long height = get_long(t, "Unable to parse height field in dummy video parameter list"); + long red = get_long(t, "Unable to parse red colour field in dummy video parameter list"); + long green = get_long(t, "Unable to parse green colour field in dummy video parameter list"); + long blue = get_long(t, "Unable to parse blue colour field in dummy video parameter list"); - field = t.GetNextToken(); - if (!field.ToLong(&_width)) { - throw VideoOpenError("Unable to parse width field in dummy video parameter list"); - } + bool pattern = t.GetNextToken() == "c"; - field = t.GetNextToken(); - if (!field.ToLong(&_height)) { - throw VideoOpenError("Unable to parse height field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&red)) { - throw VideoOpenError("Unable to parse red colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&green)) { - throw VideoOpenError("Unable to parse green colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (!field.ToLong(&blue)) { - throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list"); - } - - field = t.GetNextToken(); - if (field == "c") { - pattern = true; - } - - Create(fps, _frames, _width, _height, wxColour(red, green, blue), pattern); + Create(fps, frames, width, height, red, green, blue, pattern); } -/// @brief Direct constructor -/// @param _fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// -DummyVideoProvider::DummyVideoProvider(double _fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - Create(_fps, frames, _width, _height, colour, pattern); +DummyVideoProvider::DummyVideoProvider(double fps, int frames, int width, int height, const wxColour &colour, bool pattern) { + Create(fps, frames, width, height, colour.Red(), colour.Green(), colour.Blue(), pattern); } -/// @brief Destructor -/// DummyVideoProvider::~DummyVideoProvider() { frame.Clear(); } -/// @brief Construct a fake filename describing the video -/// @param fps -/// @param frames -/// @param _width -/// @param _height -/// @param colour -/// @param pattern -/// @return -/// -wxString DummyVideoProvider::MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern) { - return wxString::Format("?dummy:%f:%d:%d:%d:%d:%d:%d:%s", fps, frames, _width, _height, colour.Red(), colour.Green(), colour.Blue(), pattern?"c":""); -} - -/// @brief Get frame -/// @param n -/// @return -/// -const AegiVideoFrame DummyVideoProvider::GetFrame(int n) { - lastFrame = n; - return frame; +wxString DummyVideoProvider::MakeFilename(double fps, int frames, int width, int height, const wxColour &colour, bool pattern) { + return wxString::Format("?dummy:%f:%d:%d:%d:%d:%d:%d:%s", fps, frames, width, height, colour.Red(), colour.Green(), colour.Blue(), pattern ? "c" : ""); } diff --git a/aegisub/src/video_provider_dummy.h b/aegisub/src/video_provider_dummy.h index 1640151b9..7871c732b 100644 --- a/aegisub/src/video_provider_dummy.h +++ b/aegisub/src/video_provider_dummy.h @@ -34,53 +34,61 @@ /// @ingroup video_input /// -// The dummy video provider needs a header, since it needs to be created directly as a special case - -#ifndef AGI_PRE -#include -#endif - #include "include/aegisub/video_provider.h" #include "video_frame.h" -/// DOCME +class wxColour; + /// @class DummyVideoProvider -/// @brief DOCME +/// @brief A dummy video provider for when opening a file is just too much effort /// -/// DOCME +/// This simply returns a single constant frame, which can either be a flat +/// color or a checkerboard pattern class DummyVideoProvider : public VideoProvider { - /// DOCME - int lastFrame; + int framecount; ///< Length of the dummy video in frames + agi::vfr::Framerate fps; ///< Frame rate to use + int width; ///< Width in pixels + int height; ///< Height in pixels - /// DOCME - int framecount; - - /// DOCME - agi::vfr::Framerate fps; - - /// DOCME - int width; - - /// DOCME - int height; - - /// DOCME + /// The single image which is returned for all frames AegiVideoFrame frame; - void Create(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); + /// Create the dummy frame from the given parameters + /// @param fps Frame rate of the dummy video + /// @param frames Length in frames of the dummy video + /// @param width Width in pixels of the dummy video + /// @param height Height in pixels of the dummy video + /// @param red Red component of the primary colour of the dummy video + /// @param green Green component of the primary colour of the dummy video + /// @param blue Blue component of the primary colour of the dummy video + /// @param pattern Use a checkerboard pattern rather than a solid colour + void Create(double fps, int frames, int width, int height, unsigned char red, unsigned char green, unsigned char blue, bool pattern); public: - DummyVideoProvider(wxString filename); - DummyVideoProvider(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); + /// Create a dummy video from a string returned from MakeFilename + DummyVideoProvider(wxString const& filename); + + /// Create a dummy video from separate parameters + /// @param fps Frame rate of the dummy video + /// @param frames Length in frames of the dummy video + /// @param width Width in pixels of the dummy video + /// @param height Height in pixels of the dummy video + /// @param colour Primary colour of the dummy video + /// @param pattern Use a checkerboard pattern rather than a solid colour + DummyVideoProvider(double fps, int frames, int width, int height, wxColour const& colour, bool pattern); + + /// Destructor ~DummyVideoProvider(); - const AegiVideoFrame GetFrame(int n); - static wxString MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); + /// Make a fake filename which when passed to the constructor taking a + /// string will result in a video with the given parameters + static wxString MakeFilename(double fps, int frames, int width, int height, wxColour const& colour, bool pattern); - int GetFrameCount() const { return framecount; } - int GetWidth() const { return width; } - int GetHeight() const { return height; } - agi::vfr::Framerate GetFPS() const { return fps; } + const AegiVideoFrame GetFrame(int n) { return frame; } + int GetFrameCount() const { return framecount; } + int GetWidth() const { return width; } + int GetHeight() const { return height; } + agi::vfr::Framerate GetFPS() const { return fps; } std::vector GetKeyFrames() const { return std::vector(); }; - wxString GetDecoderName() const { return "Dummy Video Provider"; } + wxString GetDecoderName() const { return "Dummy Video Provider"; } };