]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoZoneDefinition.cpp
threads: Make sure we don't re-create a thread if the object has already one.
[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 // max weight to left
29 void CAtmoZoneDefinition::FillGradientFromLeft()
30 {
31    int index = 0;
32    unsigned char col_norm;
33    for(int row=0; row < CAP_HEIGHT; row++) {
34        for(int col=0; col < CAP_WIDTH; col++) {
35            // should be a value between 0 .. 255?
36            col_norm = (255 * (CAP_WIDTH-col-1)) / (CAP_WIDTH-1);
37            m_BasicWeight[index++] = col_norm;
38        }
39    }
40 }
41
42 // max weight to right
43 void CAtmoZoneDefinition::FillGradientFromRight()
44 {
45    int index = 0;
46    unsigned char col_norm;
47    for(int row=0; row < CAP_HEIGHT; row++) {
48       for(int col=0; col < CAP_WIDTH; col++) {
49           col_norm = (255 * col) / (CAP_WIDTH-1); // should be a value between 0 .. 255?
50           m_BasicWeight[index++] = col_norm;
51        }
52    }
53 }
54
55 // max weight from top
56 void CAtmoZoneDefinition::FillGradientFromTop()
57 {
58    int index = 0;
59    unsigned char row_norm;
60    for(int row=0; row < CAP_HEIGHT; row++) {
61        row_norm = (255 * (CAP_HEIGHT-row-1)) / (CAP_HEIGHT-1); // should be a value between 0 .. 255?
62        for(int col=0; col < CAP_WIDTH; col++) {
63            m_BasicWeight[index++] = row_norm;
64        }
65    }
66 }
67
68 // max weight from bottom
69 void CAtmoZoneDefinition::FillGradientFromBottom()
70 {
71    int index = 0;
72    unsigned char row_norm;
73    for(int row=0; row < CAP_HEIGHT; row++) {
74        row_norm = (255 * row) / (CAP_HEIGHT-1); // should be a value between 0 .. 255?
75        for(int col=0; col < CAP_WIDTH; col++) {
76            m_BasicWeight[index++] = row_norm;
77        }
78    }
79 }
80
81
82 int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
83 {
84   // transform 256 color image (gray scale!)
85   // into m_basicWeight or use the GREEN value of a 24bit image!
86   // channel of a true color bitmap!
87   BITMAPINFO bmpInfo;
88   BITMAPFILEHEADER  bmpFileHeader;
89
90   /*
91 #define ATMO_LOAD_GRADIENT_OK  0
92 #define ATMO_LOAD_GRADIENT_FAILED_SIZE    1
93 #define ATMO_LOAD_GRADIENT_FAILED_HEADER  2
94   */
95
96
97    FILE *bmp = fopen(pszBitmap, "rb");
98    if(!bmp)
99      return ATMO_LOAD_GRADIENT_FILENOTFOND;
100
101     if(fread(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, bmp) != 1)
102     {
103         fclose(bmp);
104         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
105     }
106 #ifdef _ATMO_VLC_PLUGIN_
107     if(bmpFileHeader.bfType != VLC_TWOCC('M','B'))
108 #else
109     if(bmpFileHeader.bfType != MakeWord('M','B'))
110 #endif
111     {
112         fclose(bmp);
113         return ATMO_LOAD_GRADIENT_FAILED_HEADER;
114     }
115
116     if(fread(&bmpInfo, sizeof(BITMAPINFO), 1, bmp) != 1)
117     {
118         fclose(bmp);
119         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
120     }
121
122     if(bmpInfo.bmiHeader.biCompression != BI_RGB)
123     {
124         fclose(bmp);
125         return ATMO_LOAD_GRADIENT_FAILED_FORMAT;
126     }
127     if((bmpInfo.bmiHeader.biBitCount != 8) && (bmpInfo.bmiHeader.biBitCount != 24))
128     {
129         fclose(bmp);
130         return ATMO_LOAD_GRADIENT_FAILED_FORMAT;
131     }
132
133     int width = bmpInfo.bmiHeader.biWidth;
134     int height = bmpInfo.bmiHeader.biHeight;
135     ATMO_BOOL invertDirection = (height > 0);
136     height = abs(height);
137     if((width != CAP_WIDTH) || (height != CAP_HEIGHT))
138     {
139         fclose(bmp);
140         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
141     }
142
143     fseek(bmp, bmpFileHeader.bfOffBits, SEEK_SET);
144
145     int imageSize = width * height * bmpInfo.bmiHeader.biBitCount/8;
146
147     unsigned char *pixelBuffer = (unsigned char *)malloc(imageSize);
148     if(fread(pixelBuffer,imageSize,1,bmp) != 1)
149     {
150         fclose(bmp);
151         return ATMO_LOAD_GRADIENT_FAILED_SIZE;
152     }
153
154     if(bmpInfo.bmiHeader.biBitCount == 8)
155     {
156         int ydest;
157         for(int y=0;y < CAP_HEIGHT; y++) {
158             if(invertDirection) {
159                 ydest = (CAP_HEIGHT - y - 1);
160             } else {
161                 ydest = y;
162             }
163             for(int x=0;x < CAP_WIDTH; x++) {
164                 // palette should be grey scale - so that index 0 is black and
165                 // index 255 means white!
166                 // everything else would produce funny results!
167                 m_BasicWeight[ydest * CAP_WIDTH + x] =
168                     pixelBuffer[y * CAP_WIDTH + x];
169             }
170         }
171     }
172
173     if(bmpInfo.bmiHeader.biBitCount == 24)
174     {
175         int ydest;
176         for(int y=0;y < CAP_HEIGHT; y++) {
177             if(invertDirection) {
178                 ydest = (CAP_HEIGHT - y - 1);
179             } else {
180                 ydest = y;
181             }
182             for(int x=0;x < CAP_WIDTH; x++) {
183                 // use the green value as reference...
184                 m_BasicWeight[ydest * CAP_WIDTH + x] =
185                     pixelBuffer[y * CAP_WIDTH * 3 + (x*3) + 1 ];
186             }
187         }
188     }
189     free(pixelBuffer);
190     fclose(bmp);
191
192     return ATMO_LOAD_GRADIENT_OK;
193 }
194
195
196 void CAtmoZoneDefinition::UpdateWeighting(int *destWeight,
197                                           int WidescreenMode,
198                                           int newEdgeWeightning)
199 {
200   /*
201     use the values in m_BasicWeight and newWeightning to
202     update the direct control array for the output thread!
203   */
204
205   int index = 0;
206   for(int row=0; row < CAP_HEIGHT; row++) {
207       for(int col=0; col < CAP_HEIGHT; col++) {
208           if ((WidescreenMode == 1) && ((row <= CAP_HEIGHT/8) || (row >= (7*CAP_HEIGHT)/8)))
209           {
210              destWeight[index] = 0;
211           } else {
212                      destWeight[index] = (int)(255.0 * (float)pow( ((float)m_BasicWeight[index])/255.0 , newEdgeWeightning));
213           }
214           index++;
215       }
216   }
217 }
218
219 void CAtmoZoneDefinition::setZoneNumber(int num)
220 {
221     m_zonenumber = num;
222 }
223
224 int CAtmoZoneDefinition::getZoneNumber()
225 {
226     return m_zonenumber;
227 }
228
229