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