MythTV  master
Bitmap.cpp
Go to the documentation of this file.
1 /* Bitmap.cpp
2 
3  Copyright (C) David C. J. Matthews 2004, 2008 dm at prolingua.co.uk
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  as published by the Free Software Foundation; either version 2
8  of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  Or, point your browser to http://www.gnu.org/copyleft/gpl.html
19 
20 */
21 
22 #include "Bitmap.h"
23 #include "Visible.h"
24 #include "Presentable.h"
25 #include "Ingredients.h"
26 #include "Root.h"
27 #include "BaseClasses.h"
28 #include "ParseNode.h"
29 #include "ASN1Codes.h"
30 #include "Engine.h"
31 #include "Logging.h"
32 #include "freemheg.h"
33 
34 #include <cinttypes>
35 
36 /*
37 UK MHEG content hook values: 2 => MPEG I-frame, 4 => PNG bitmap
38 */
39 
41 {
42  delete(m_pContent);
43 }
44 
46 {
47  MHVisible::Initialise(p, engine);
48  // Tiling - optional
49  MHParseNode *pTiling = p->GetNamedArg(C_TILING);
50 
51  if (pTiling)
52  {
53  m_fTiling = pTiling->GetArgN(0)->GetBoolValue();
54  }
55 
56  // Transparency - optional
57  MHParseNode *pTransparency = p->GetNamedArg(C_ORIGINAL_TRANSPARENCY);
58 
59  if (pTransparency)
60  {
61  m_nOrigTransparency = pTransparency->GetArgN(0)->GetIntValue();
62  }
63 
65 }
66 
67 void MHBitmap::PrintMe(FILE *fd, int nTabs) const
68 {
69  PrintTabs(fd, nTabs);
70  fprintf(fd, "{:Bitmap ");
71  MHVisible::PrintMe(fd, nTabs + 1);
72 
73  if (m_fTiling)
74  {
75  PrintTabs(fd, nTabs + 1);
76  fprintf(fd, ":Tiling true\n");
77  }
78 
79  if (m_nOrigTransparency != 0)
80  {
81  PrintTabs(fd, nTabs + 1);
82  fprintf(fd, ":OrigTransparency %d\n", m_nOrigTransparency);
83  }
84 
85  PrintTabs(fd, nTabs);
86  fprintf(fd, "}\n");
87 }
88 
90 {
91  if (m_fAvailable)
92  {
93  return;
94  }
95 
96  m_nTransparency = m_nOrigTransparency; // Transparency isn't used in UK MHEG
97  MHVisible::Preparation(engine);
98 }
99 
100 //
102 {
104 
105  if (m_ContentType == IN_NoContent)
106  {
107  MHERROR("Bitmap must contain a content");
108  }
109 
110  if (m_ContentType == IN_IncludedContent)
112 }
113 
114 // Decode the content.
115 void MHBitmap::ContentArrived(const unsigned char *data, int length, MHEngine *engine)
116 {
117  QRegion updateArea = GetVisibleArea(); // If there's any content already we have to redraw it.
118 
119  if (! m_pContent)
120  {
121  return; // Shouldn't happen.
122  }
123 
124  CreateContent(data, length, engine);
125  // Now signal that the content is available.
126  engine->EventTriggered(this, EventContentAvailable);
127 }
128 
129 void MHBitmap::CreateContent(const unsigned char *data, int length, MHEngine *engine)
130 {
131  QRegion updateArea = GetVisibleArea(); // If there's any content already we have to redraw it.
132 
133  int nCHook = m_nContentHook;
134 
135  if (nCHook == 0)
136  {
137  nCHook = engine->GetDefaultBitmapCHook();
138  }
139 
140  switch (nCHook)
141  {
142  case 4: // PNG.
143  m_pContent->CreateFromPNG(data, length);
144  break;
145  case 2: // MPEG I-frame.
146  case 5: // BBC/Freesat MPEG I-frame background
147  m_pContent->CreateFromMPEG(data, length);
148  break;
149  case 6: // JPEG ISO/IEC 10918-1, JFIF file
150  m_pContent->CreateFromJPEG(data, length);
151  break;
152  default: // 1,3,5,8 are reserved. 7= H.264 Intra Frame
153  MHERROR(QString("Unknown bitmap content hook %1").arg(nCHook));
154  }
155 
156  updateArea += GetVisibleArea(); // Redraw this bitmap.
157  engine->Redraw(updateArea); // Mark for redrawing
158 }
159 
160 
161 // Set the transparency.
162 void MHBitmap::SetTransparency(int nTransPerCent, MHEngine * /*engine*/)
163 {
164  // The object transparency isn't actually used in UK MHEG.
165  // We want a value between 0 and 255
166  if (nTransPerCent < 0)
167  {
168  nTransPerCent = 0; // Make sure it's in the bounds
169  }
170 
171  if (nTransPerCent > 100)
172  {
173  nTransPerCent = 100;
174  }
175 
176  m_nTransparency = ((nTransPerCent * 255) + 50) / 100;
177 }
178 
179 // Scale a bitmap. In UK MHEG this is only used for MPEG I-frames, not PNG.
180 void MHBitmap::ScaleBitmap(int xScale, int yScale, MHEngine *engine)
181 {
182  QRegion updateArea = GetVisibleArea(); // If there's any content already we have to redraw it.
183  m_pContent->ScaleImage(xScale, yScale);
184  updateArea += GetVisibleArea(); // Redraw this bitmap.
185  engine->Redraw(updateArea); // Mark for redrawing
186 }
187 
188 // Added action in UK MHEG.
189 void MHBitmap::SetBitmapDecodeOffset(int newXOffset, int newYOffset, MHEngine *engine)
190 {
191  QRegion updateArea = GetVisibleArea(); // Redraw the area before the offset
192  m_nXDecodeOffset = newXOffset;
193  m_nYDecodeOffset = newYOffset;
194  updateArea += GetVisibleArea(); // Redraw this bitmap.
195  engine->Redraw(updateArea); // Mark for redrawing
196 }
197 
198 // Added action in UK MHEG.
200 {
203 }
204 
205 void MHBitmap::Display(MHEngine * /*engine*/)
206 {
207  if (! m_fRunning || ! m_pContent || m_nBoxWidth == 0 || m_nBoxHeight == 0)
208  {
209  return; // Can't draw zero sized boxes.
210  }
211 
214  m_nContentHook == 5); // 'under video' if BBC MPEG I-frame background
215 }
216 
217 // Return the region drawn by the bitmap.
219 {
220  if (! m_fRunning || m_pContent == nullptr)
221  {
222  return QRegion();
223  }
224 
225  // The visible area is the intersection of the containing box with the, possibly offset,
226  // bitmap.
227  QSize imageSize = m_pContent->GetSize();
228  QRegion boxRegion = QRegion(m_nPosX, m_nPosY, m_nBoxWidth, m_nBoxHeight);
229  QRegion bitmapRegion = QRegion(m_nPosX + m_nXDecodeOffset, m_nPosY + m_nYDecodeOffset,
230  imageSize.width(), imageSize.height());
231  return boxRegion & bitmapRegion;
232 }
233 
234 // Return the area actually obscured by the bitmap.
236 {
237  // The area is empty unless the bitmap is opaque.
238  // and it's not a BBC MPEG I-frame background
239  if (! m_fRunning || m_nContentHook == 5 || m_pContent == nullptr || ! m_pContent->IsOpaque())
240  {
241  return QRegion();
242  }
243  return GetVisibleArea();
244 }
245 
void Display(MHEngine *d) override
Definition: Bitmap.cpp:205
#define MHERROR(__text)
Definition: Logging.h:42
MHBitmapDisplay * m_pContent
Definition: Bitmap.h:76
virtual void CreateFromPNG(const unsigned char *data, int length)=0
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Bitmap.cpp:45
virtual void SetVariableValue(const MHUnion &)
Definition: Root.h:101
void PrintMe(FILE *fd, int nTabs) const override
Definition: Visible.cpp:84
void SetTransparency(int nTransPerCent, MHEngine *) override
Definition: Bitmap.cpp:162
int m_nBoxWidth
Definition: Visible.h:79
void ContentArrived(const unsigned char *data, int length, MHEngine *engine) override
Definition: Bitmap.cpp:115
bool m_fAvailable
Definition: Root.h:207
int m_nPosY
Definition: Visible.h:82
void GetBitmapDecodeOffset(MHRoot *pXOffset, MHRoot *pYOffset) override
Definition: Bitmap.cpp:199
enum MHIngredient::@10 IN_NoContent
void PrintMe(FILE *fd, int nTabs) const override
Definition: Bitmap.cpp:67
const unsigned char * Bytes() const
Definition: BaseClasses.h:122
QRegion GetOpaqueArea() override
Definition: Bitmap.cpp:235
virtual bool IsOpaque()=0
int m_nContentHook
Definition: Ingredients.h:66
int m_nOrigTransparency
Definition: Bitmap.h:68
MHContext * GetContext()
Definition: Engine.h:153
void SetBitmapDecodeOffset(int newXOffset, int newYOffset, MHEngine *engine) override
Definition: Bitmap.cpp:189
void Redraw(const QRegion &region)
Definition: Engine.cpp:901
int m_nYDecodeOffset
Definition: Bitmap.h:74
int GetDefaultBitmapCHook()
Definition: Engine.cpp:1450
void ContentPreparation(MHEngine *engine) override
virtual QSize GetSize()=0
void PrintTabs(FILE *fd, int n)
Definition: ParseNode.cpp:34
#define C_TILING
Definition: ASN1Codes.h:112
int Size() const
Definition: BaseClasses.h:117
void Preparation(MHEngine *engine) override
Definition: Bitmap.cpp:89
int m_nPosX
Definition: Visible.h:81
int GetIntValue()
Definition: ParseNode.cpp:170
virtual void ScaleImage(int newWidth, int newHeight)=0
void EventTriggered(MHRoot *pSource, enum EventType ev)
Definition: Engine.h:93
QRegion GetVisibleArea() override
Definition: Bitmap.cpp:218
void Preparation(MHEngine *engine) override
Definition: Visible.cpp:105
MHParseNode * GetNamedArg(int nTag)
Definition: ParseNode.cpp:110
bool m_fTiling
Definition: Bitmap.h:67
void Initialise(MHParseNode *p, MHEngine *engine) override
Definition: Visible.cpp:50
Definition: Root.h:43
bool m_fRunning
Definition: Root.h:208
int FILE
Definition: mythburn.py:110
void ContentPreparation(MHEngine *engine) override
Definition: Bitmap.cpp:101
int m_nTransparency
Definition: Bitmap.h:71
#define C_ORIGINAL_TRANSPARENCY
Definition: ASN1Codes.h:113
MHOctetString m_IncludedContent
Definition: Ingredients.h:77
virtual void CreateFromMPEG(const unsigned char *data, int length)=0
virtual void Draw(int x, int y, QRect rect, bool tiled, bool bUnder)=0
virtual ~MHBitmap()
Definition: Bitmap.cpp:40
void CreateContent(const unsigned char *data, int length, MHEngine *engine)
Definition: Bitmap.cpp:129
void ScaleBitmap(int xScale, int yScale, MHEngine *engine) override
Definition: Bitmap.cpp:180
virtual MHBitmapDisplay * CreateBitmap(bool tiled)=0
bool GetBoolValue()
Definition: ParseNode.cpp:192
MHParseNode * GetArgN(int n)
Definition: ParseNode.cpp:78
int m_nXDecodeOffset
Definition: Bitmap.h:73
virtual void CreateFromJPEG(const unsigned char *data, int length)=0
int m_nBoxHeight
Definition: Visible.h:80