OpenShot Library | libopenshot  0.4.0
Deinterlace.cpp
Go to the documentation of this file.
1 
9 // Copyright (c) 2008-2019 OpenShot Studios, LLC
10 //
11 // SPDX-License-Identifier: LGPL-3.0-or-later
12 
13 #include "Deinterlace.h"
14 #include "Exceptions.h"
15 #include <omp.h>
16 
17 using namespace openshot;
18 
20 Deinterlace::Deinterlace() : isOdd(true)
21 {
22  // Init effect properties
23  init_effect_details();
24 }
25 
26 // Default constructor
27 Deinterlace::Deinterlace(bool UseOddLines) : isOdd(UseOddLines)
28 {
29  // Init effect properties
30  init_effect_details();
31 }
32 
33 // Init effect settings
34 void Deinterlace::init_effect_details()
35 {
38 
40  info.class_name = "Deinterlace";
41  info.name = "Deinterlace";
42  info.description = "Remove interlacing from a video (i.e. even or odd horizontal lines)";
43  info.has_audio = false;
44  info.has_video = true;
45 }
46 
47 // This method is required for all derived classes of EffectBase, and returns a
48 // modified openshot::Frame object
49 std::shared_ptr<openshot::Frame> Deinterlace::GetFrame(std::shared_ptr<openshot::Frame> frame, int64_t frame_number)
50 {
51  // Get original size of frame's image
52  int original_width = frame->GetImage()->width();
53  int original_height = frame->GetImage()->height();
54 
55  // Access the current QImage and its raw pixel data
56  auto image = frame->GetImage();
57  const unsigned char* pixels = image->bits();
58  int line_bytes = image->bytesPerLine();
59 
60  // Decide whether to copy even lines (start = 0) or odd lines (start = 1)
61  int start = isOdd ? 1 : 0;
62 
63  // Compute how many rows we will end up copying
64  // If start = 0, rows_to_copy = ceil(original_height / 2.0)
65  // If start = 1, rows_to_copy = floor(original_height / 2.0)
66  int rows_to_copy = (original_height - start + 1) / 2;
67 
68  // Create a new image with exactly 'rows_to_copy' scanlines
69  QImage deinterlaced_image(
70  original_width,
71  rows_to_copy,
72  QImage::Format_RGBA8888_Premultiplied
73  );
74  unsigned char* deinterlaced_pixels = deinterlaced_image.bits();
75 
76  // Copy every other row from the source into the new image
77  // Parallelize over 'i' so each thread writes to a distinct slice of memory
78 #pragma omp parallel for
79  for (int i = 0; i < rows_to_copy; i++) {
80  int row = start + 2 * i;
81  const unsigned char* src = pixels + (row * line_bytes);
82  unsigned char* dst = deinterlaced_pixels + (i * line_bytes);
83  memcpy(dst, src, line_bytes);
84  }
85 
86  // Resize deinterlaced image back to original size, and update frame's image
87  image = std::make_shared<QImage>(deinterlaced_image.scaled(
88  original_width, original_height,
89  Qt::IgnoreAspectRatio, Qt::FastTransformation));
90 
91  // Update image on frame
92  frame->AddImage(image);
93 
94  // return the modified frame
95  return frame;
96 }
97 
98 // Generate JSON string of this object
99 std::string Deinterlace::Json() const {
100 
101  // Return formatted string
102  return JsonValue().toStyledString();
103 }
104 
105 // Generate Json::Value for this object
106 Json::Value Deinterlace::JsonValue() const {
107 
108  // Create root json object
109  Json::Value root = EffectBase::JsonValue(); // get parent properties
110  root["type"] = info.class_name;
111  root["isOdd"] = isOdd;
112 
113  // return JsonValue
114  return root;
115 }
116 
117 // Load JSON string into this object
118 void Deinterlace::SetJson(const std::string value) {
119 
120  // Parse JSON string into JSON objects
121  try
122  {
123  const Json::Value root = openshot::stringToJson(value);
124  // Set all values that match
125  SetJsonValue(root);
126  }
127  catch (const std::exception& e)
128  {
129  // Error parsing JSON (or missing keys)
130  throw InvalidJSON("JSON is invalid (missing keys or invalid data types)");
131  }
132 }
133 
134 // Load Json::Value into this object
135 void Deinterlace::SetJsonValue(const Json::Value root) {
136 
137  // Set parent data
139 
140  // Set data from Json (if key is found)
141  if (!root["isOdd"].isNull())
142  isOdd = root["isOdd"].asBool();
143 }
144 
145 // Get all properties for a specific frame
146 std::string Deinterlace::PropertiesJSON(int64_t requested_frame) const {
147 
148  // Generate JSON properties list
149  Json::Value root = BasePropertiesJSON(requested_frame);
150 
151  // Add Is Odd Frame choices (dropdown style)
152  root["isOdd"] = add_property_json("Is Odd Frame", isOdd, "bool", "", NULL, 0, 1, false, requested_frame);
153  root["isOdd"]["choices"].append(add_property_choice_json("Yes", true, isOdd));
154  root["isOdd"]["choices"].append(add_property_choice_json("No", false, isOdd));
155 
156  // Return formatted string
157  return root.toStyledString();
158 }
openshot::ClipBase::add_property_json
Json::Value add_property_json(std::string name, float value, std::string type, std::string memo, const Keyframe *keyframe, float min_value, float max_value, bool readonly, int64_t requested_frame) const
Generate JSON for a property.
Definition: ClipBase.cpp:96
openshot::stringToJson
const Json::Value stringToJson(const std::string value)
Definition: Json.cpp:16
openshot::Deinterlace::JsonValue
Json::Value JsonValue() const override
Generate Json::Value for this object.
Definition: Deinterlace.cpp:106
openshot::EffectBase::info
EffectInfoStruct info
Information about the current effect.
Definition: EffectBase.h:69
openshot
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:28
openshot::Deinterlace::Json
std::string Json() const override
Generate JSON string of this object.
Definition: Deinterlace.cpp:99
openshot::ClipBase::add_property_choice_json
Json::Value add_property_choice_json(std::string name, int value, int selected_value) const
Generate JSON choice for a property (dropdown properties)
Definition: ClipBase.cpp:132
openshot::EffectBase::JsonValue
virtual Json::Value JsonValue() const
Generate Json::Value for this object.
Definition: EffectBase.cpp:79
openshot::Deinterlace::Deinterlace
Deinterlace()
Default constructor, useful when using Json to load the effect properties.
Definition: Deinterlace.cpp:20
openshot::Deinterlace::PropertiesJSON
std::string PropertiesJSON(int64_t requested_frame) const override
Definition: Deinterlace.cpp:146
openshot::EffectBase::BasePropertiesJSON
Json::Value BasePropertiesJSON(int64_t requested_frame) const
Generate JSON object of base properties (recommended to be used by all effects)
Definition: EffectBase.cpp:179
openshot::InvalidJSON
Exception for invalid JSON.
Definition: Exceptions.h:217
openshot::EffectBase::InitEffectInfo
void InitEffectInfo()
Definition: EffectBase.cpp:24
openshot::EffectInfoStruct::has_audio
bool has_audio
Determines if this effect manipulates the audio of a frame.
Definition: EffectBase.h:41
openshot::ClipBase::start
float start
The position in seconds to start playing (used to trim the beginning of a clip)
Definition: ClipBase.h:37
openshot::EffectInfoStruct::class_name
std::string class_name
The class name of the effect.
Definition: EffectBase.h:36
openshot::EffectInfoStruct::description
std::string description
The description of this effect and what it does.
Definition: EffectBase.h:38
openshot::EffectInfoStruct::has_video
bool has_video
Determines if this effect manipulates the image of a frame.
Definition: EffectBase.h:40
openshot::Deinterlace::SetJson
void SetJson(const std::string value) override
Load JSON string into this object.
Definition: Deinterlace.cpp:118
openshot::Deinterlace::SetJsonValue
void SetJsonValue(const Json::Value root) override
Load Json::Value into this object.
Definition: Deinterlace.cpp:135
openshot::Deinterlace::GetFrame
std::shared_ptr< openshot::Frame > GetFrame(int64_t frame_number) override
This method is required for all derived classes of ClipBase, and returns a new openshot::Frame object...
Definition: Deinterlace.h:56
openshot::EffectInfoStruct::name
std::string name
The name of the effect.
Definition: EffectBase.h:37
Deinterlace.h
Header file for De-interlace class.
Exceptions.h
Header file for all Exception classes.
openshot::EffectBase::SetJsonValue
virtual void SetJsonValue(const Json::Value root)
Load Json::Value into this object.
Definition: EffectBase.cpp:115