]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoZoneDefinition.cpp
Use var_InheritString for --decklink-video-connection.
[vlc] / modules / video_filter / atmo / AtmoZoneDefinition.cpp
1
2 #include "AtmoDefs.h"
3
4 #if defined (WIN32)
5 #  include <windows.h>
6 #else
7 #  include <vlc_codecs.h>
8 #endif
9
10 #include <math.h>
11 #include <stdio.h>
12 #include "AtmoZoneDefinition.h"
13
14 CAtmoZoneDefinition::CAtmoZoneDefinition(void)
15 {
16 }
17
18 CAtmoZoneDefinition::~CAtmoZoneDefinition(void)
19 {
20 }
21
22 void CAtmoZoneDefinition::Fill(unsigned char value)
23 {
24   for(int i=0; i < IMAGE_SIZE; i++)
25       m_BasicWeight[i] = value;
26 }
27
28
29 // max weight to left
30 void CAtmoZoneDefinition::FillGradientFromLeft(int start_row,int end_row)
31 {
32    int index;
33    unsigned char col_norm;
34    index = start_row * CAP_WIDTH;
35    for(int row=start_row; row < end_row; row++) {
36        for(int col=0; col < CAP_WIDTH; col++) {
37            // should be a value between 0 .. 255?
38            col_norm = (255 * (CAP_WIDTH-col-1)) / (CAP_WIDTH-1);
39            m_BasicWeight[index++] = col_norm;
40        }
41    }
42 }
43
44 // max weight to right
45 void CAtmoZoneDefinition::FillGradientFromRight(int start_row,int end_row)
46 {
47    int index;
48    unsigned char col_norm;
49    index = start_row * CAP_WIDTH;
50    for(int row=start_row; row < end_row; row++) {
51       for(int col=0; col < CAP_WIDTH; col++) {
52           col_norm = (255 * col) / (CAP_WIDTH-1); // should be a value between 0 .. 255?
53           m_BasicWeight[index++] = col_norm;
54        }
55    }
56 }
57
58 // max weight from top
59 void CAtmoZoneDefinition::FillGradientFromTop(int start_col,int end_col)
60 {
61    int index;
62    unsigned char row_norm;
63
64    for(int row=0; row < CAP_HEIGHT; row++) {
65        index = row * CAP_WIDTH + start_col;
66
67        row_norm = (255 * (CAP_HEIGHT-row-1)) / (CAP_HEIGHT-1); // should be a value between 0 .. 255?
68        for(int col=start_col; col < end_col; col++) {
69            m_BasicWeight[index++] = row_norm;
70        }
71    }
72 }
73
74 // max weight from bottom
75 void CAtmoZoneDefinition::FillGradientFromBottom(int start_col,int end_col)
76 {
77    int index;
78    unsigned char row_norm;
79    for(int row=0; row < CAP_HEIGHT; row++) {
80        index = row * CAP_WIDTH + start_col;
81        row_norm = (255 * row) / (CAP_HEIGHT-1); // should be a value between 0 .. 255?
82        for(int col=start_col; col < end_col; col++) {
83            m_BasicWeight[index++] = row_norm;
84        }
85    }
86 }
87
88 #if !defined(_ATMO_VLC_PLUGIN_)
89
90 void CAtmoZoneDefinition::SaveZoneBitmap(char *fileName)
91 {
92      if(!fileName) return;
93
94      BITMAPINFO bmpInfo;
95      // BITMAPINFOHEADER
96      BITMAPFILEHEADER  bmpFileHeader;
97      ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
98      bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
99
100
101      bmpInfo.bmiHeader.biHeight = -CAP_HEIGHT;
102      bmpInfo.bmiHeader.biWidth  = CAP_WIDTH;
103      bmpInfo.bmiHeader.biSizeImage = abs(bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 3;
104
105      unsigned char *pBuf = (unsigned char *)malloc(bmpInfo.bmiHeader.biSizeImage);
106      for(int y=0; y < CAP_HEIGHT; y++ )
107      {
108          for(int x=0; x < CAP_WIDTH; x++)
109          {
110              pBuf[y * CAP_WIDTH * 3 + x * 3 ] = 0;
111              pBuf[y * CAP_WIDTH * 3 + x * 3 + 1 ] = m_BasicWeight[y * CAP_WIDTH + x];
112              pBuf[y * CAP_WIDTH * 3 + x * 3 + 2] = 0;
113          }
114      }
115
116      bmpInfo.bmiHeader.biCompression = BI_RGB;
117      bmpInfo.bmiHeader.biPlanes = 1;
118      bmpInfo.bmiHeader.biBitCount = 24;
119
120      bmpFileHeader.bfReserved1=0;
121      bmpFileHeader.bfReserved2=0;
122      bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
123      bmpFileHeader.bfType = MakeIntelWord('M','B');
124      bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
125
126
127      FILE *fp = NULL;
128      fp = fopen(fileName,"wb");
129      fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
130      fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
131      fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);
132      fclose(fp);
133 }
134
135 void CAtmoZoneDefinition::SaveWeightBitmap(char *fileName,int *weight)
136 {
137      if(!fileName || !weight) return;
138
139      BITMAPINFO bmpInfo;
140      // BITMAPINFOHEADER
141      BITMAPFILEHEADER  bmpFileHeader;
142      ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
143      bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
144
145
146      bmpInfo.bmiHeader.biHeight = -CAP_HEIGHT;
147      bmpInfo.bmiHeader.biWidth  = CAP_WIDTH;
148      bmpInfo.bmiHeader.biSizeImage = abs(bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 3;
149
150      unsigned char *pBuf = (unsigned char *)malloc(bmpInfo.bmiHeader.biSizeImage);
151      for(int y=0; y < CAP_HEIGHT; y++ )
152      {
153          for(int x=0; x < CAP_WIDTH; x++)
154          {
155              pBuf[y * CAP_WIDTH * 3 + x * 3 ] = 0;
156              pBuf[y * CAP_WIDTH * 3 + x * 3 + 1 ] = (unsigned char)weight[y * CAP_WIDTH + x];
157              pBuf[y * CAP_WIDTH * 3 + x * 3 + 2] = 0;
158          }
159      }
160
161      bmpInfo.bmiHeader.biCompression = BI_RGB;
162      bmpInfo.bmiHeader.biPlanes = 1;
163      bmpInfo.bmiHeader.biBitCount = 24;
164
165      bmpFileHeader.bfReserved1=0;
166      bmpFileHeader.bfReserved2=0;
167      bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
168      bmpFileHeader.bfType = MakeIntelWord('M','B');
169      bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
170
171
172      FILE *fp = NULL;
173      fp = fopen(fileName,"wb");
174      fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
175      fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
176      fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);
177      fclose(fp);
178 }
179
180
181 #endif
182
183
184
185 int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
186 {
187   // transform 256 color image (gray scale!)
188   // into m_basicWeight or use the GREEN value of a 24bit image!
189   // channel of a true color bitmap!
190   BITMAPINFO bmpInfo;
191   BITMAPFILEHEADER  bmpFileHeader;
192
193   /*
194   ATMO_LOAD_GRADIENT_FILENOTFOND
195 #define ATMO_LOAD_GRADIENT_OK  0
196 #define ATMO_LOAD_GRADIENT_FAILED_SIZE    1
197 #define ATMO_LOAD_GRADIENT_FAILED_HEADER  2
198   */
199
200
201    FILE *bmp = fopen(pszBitmap, "rb");
202    if(!bmp)
203     return ATMO_LOAD_GRADIENT_FILENOTFOND;
204
205     if(fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, bmp) != 1)
206     {
207         fclose(bmp);
208         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
209     }
210
211     if(bmpFileHeader.bfType != MakeIntelWord('M','B'))
212     {
213         fclose(bmp);
214         return ATMO_LOAD_GRADIENT_FAILED_HEADER;
215     }
216
217     if(fread(&bmpInfo, sizeof(BITMAPINFO), 1, bmp) != 1)
218     {
219         fclose(bmp);
220         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
221     }
222
223     if(bmpInfo.bmiHeader.biCompression != BI_RGB)
224     {
225         fclose(bmp);
226         return ATMO_LOAD_GRADIENT_FAILED_FORMAT;
227     }
228     if((bmpInfo.bmiHeader.biBitCount != 8) && (bmpInfo.bmiHeader.biBitCount != 24))
229     {
230         fclose(bmp);
231         return ATMO_LOAD_GRADIENT_FAILED_FORMAT;
232     }
233
234     int width = bmpInfo.bmiHeader.biWidth;
235     int height = bmpInfo.bmiHeader.biHeight;
236     ATMO_BOOL invertDirection = (height > 0);
237     height = abs(height);
238     if((width != CAP_WIDTH) || (height != CAP_HEIGHT))
239     {
240         fclose(bmp);
241         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
242     }
243
244     fseek(bmp, bmpFileHeader.bfOffBits, SEEK_SET);
245
246     int imageSize = width * height * bmpInfo.bmiHeader.biBitCount/8;
247
248     unsigned char *pixelBuffer = (unsigned char *)malloc(imageSize);
249     if(fread(pixelBuffer,imageSize,1,bmp) != 1)
250     {
251         fclose(bmp);
252         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
253     }
254
255     if(bmpInfo.bmiHeader.biBitCount == 8)
256     {
257         int ydest;
258         for(int y=0;y < CAP_HEIGHT; y++) {
259             if(invertDirection) {
260                 ydest = (CAP_HEIGHT - y - 1);
261             } else {
262                 ydest = y;
263             }
264             for(int x=0;x < CAP_WIDTH; x++) {
265                 // palette should be grey scale - so that index 0 is black and
266                 // index 255 means white!
267                 // everything else would produce funny results!
268                 m_BasicWeight[ydest * CAP_WIDTH + x] =
269                     pixelBuffer[y * CAP_WIDTH + x];
270             }
271         }
272     }
273
274     if(bmpInfo.bmiHeader.biBitCount == 24)
275     {
276         int ydest;
277         for(int y=0;y < CAP_HEIGHT; y++) {
278             if(invertDirection) {
279                 ydest = (CAP_HEIGHT - y - 1);
280             } else {
281                 ydest = y;
282             }
283             for(int x=0;x < CAP_WIDTH; x++) {
284                 // use the green value as reference...
285                 m_BasicWeight[ydest * CAP_WIDTH + x] =
286                     pixelBuffer[y * CAP_WIDTH * 3 + (x*3) + 1 ];
287             }
288         }
289     }
290     free(pixelBuffer);
291     fclose(bmp);
292
293     return ATMO_LOAD_GRADIENT_OK;
294 }
295
296
297 void CAtmoZoneDefinition::UpdateWeighting(int *destWeight,
298                                           int WidescreenMode,
299                                           int newEdgeWeightning)
300 {
301   /*
302     use the values in m_BasicWeight and newWeightning to
303     update the direct control array for the output thread!
304   */
305
306   int index = 0;
307   for(int row=0; row < CAP_HEIGHT; row++) {
308       for(int col=0; col < CAP_WIDTH; col++) {
309           if ((WidescreenMode == 1) && ((row <= CAP_HEIGHT/8) || (row >= (7*CAP_HEIGHT)/8)))
310           {
311              destWeight[index] = 0;
312           } else {
313                      destWeight[index] = (int)(255.0 * (float)pow( ((float)m_BasicWeight[index])/255.0 , newEdgeWeightning));
314           }
315           index++;
316       }
317   }
318 }
319
320 void CAtmoZoneDefinition::setZoneNumber(int num)
321 {
322     m_zonenumber = num;
323 }
324
325 int CAtmoZoneDefinition::getZoneNumber()
326 {
327     return m_zonenumber;
328 }
329
330