]> git.vomp.tv Git - vompclient-marten.git/blob - wjpegcomplex.h
Fix bug in demuxer widescreen signaling
[vompclient-marten.git] / wjpegcomplex.h
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #ifndef WJPEGCOMPLEX_H
22 #define WJPEGCOMPLEX_H
23
24 // This is the complex jpeg readeing stuff not supported on all plattforms
25
26
27 #include <stdio.h>
28 #include <malloc.h>
29
30 #include "wjpeg.h"
31
32 #ifdef WIN32
33
34 #include <winsock2.h>
35 #include <windows.h>
36
37
38 //#define NEED_FAR_POINTERS
39 #define XMD_H //workaround some compiling issues
40 #endif
41
42 class Surface;
43 class Boxx;
44
45 //a reader to be implemented by the caller
46 class JpegReader {
47   public:
48   //read the next chunk of jpeg data
49   //offset - from start of file
50   //len I buf len (max bytes to read)
51   //return read len, 0 on EOF, -1 on error, *buf set to buffer
52   //will be released with free(!!!) after decoding
53   virtual ULONG readChunk(ULONG offset,ULONG len,char **buf)=0;
54   //a callback when the drawing is complete
55   //the implementation is optional
56   virtual void drawingDone(){};
57   //get the size of the current picture
58   virtual ULONG getSize(){ return 0;}
59   virtual ~JpegReader(){};
60 };
61 class WJpegComplex : public WJpeg
62 {
63   public:
64   
65     // temp for boxx
66     void setDimensions(int width, int height) {area.w=width;area.h=height;};
67   
68   
69     WJpegComplex();
70     virtual ~WJpegComplex();
71     //old style usage - load local file
72     //the sequence is init(filename), draw
73     //the new usage is drawJpeg (with having the right offsets computed)
74     int init(const char* fileName);
75     void draw();
76
77     bool hasError();
78     
79     //mode for scaling pictures
80     enum ScaleMode {
81         LETTER=0,
82         CROP=1,
83         CROPPERCENT=2};
84     //rotations
85     enum Rotation{
86      ROT_0=0,
87      ROT_90=1,
88      ROT_180=2,
89      ROT_270=3
90     };
91     //jpeg info 
92     struct JpegControl {
93       public:
94       //the available drawing area
95       Region area;
96       bool enlarge;
97       //the maximum allowed scale factor after decompress
98       UINT scaleafter;
99       //the scale mode
100       enum ScaleMode mode;
101       //the size value if scaleMode==cropPercent
102       //%of the drawing area size
103       UINT  scaleAmount;
104       //the rotation (user defined as input)
105       //if exif rotation is found this will be added
106       enum Rotation rotation;
107
108       //paremeters filled during Jpeg parsing
109       enum Rotation exifRotation;
110       char exifDate[30];
111       char error[100];
112       UINT picw;
113       UINT pich;
114       ULONG compressedSize;
115
116       //parameters computed to display picture
117       enum Rotation finalRotation;
118       //scale in %
119       UINT scale;
120       JpegControl() {
121         area.x=0;
122         area.y=0;
123         area.w=0;
124         area.h=0;
125         enlarge=false;
126         scaleafter=3;
127         scaleAmount=110;
128         mode=CROPPERCENT;
129         rotation=ROT_0;
130         exifRotation=ROT_0;
131         finalRotation=ROT_0;
132         exifDate[0]='\0';
133         error[0]='\0';
134         picw=0;
135         pich=0;
136         compressedSize=0;
137         scale=100;
138       }
139     };
140
141     //the standalone drawing function
142     //this will draw into the provided surface
143     //the reader has to be initialized before
144     //calling this function does not need a WJpeg being instantiated
145     //it simply draws into the surface
146     bool static drawJpeg(JpegControl * control, Surface* sfc, JpegReader *rdr, DrawStyle & backgroundColour);
147
148   private:
149     //our drawPixel with considers rotation
150     /* handle picture rotation
151        90: xr=h-y
152            yr=x
153        180:xr=w-x
154            yr=h-y
155        270:xr=y
156            yr=w-x
157     */
158 #ifndef __ANDROID__
159     inline static void  drawPixel(Surface * sfc,enum Rotation rotate,int x, int y,int w,int h,int xpos, int ypos,Colour c){
160     int xb=0;
161     int yb=0;
162     switch(rotate) {
163        case ROT_0:
164           xb=x;
165           yb=y;
166           break;
167        case ROT_90:
168           xb=h-y;
169           yb=x;
170           break;
171        case ROT_180:
172           xb=w-x;
173           yb=h-y;
174           break;
175        case ROT_270:
176           xb=y;
177           yb=w-x;
178           break;
179        }
180        xb+=xpos;
181        yb+=ypos;
182        if (xb < 0 || yb < 0 ) {
183          return;
184        }
185        sfc->drawPixel((UINT)xb,(UINT)yb,c,true);
186     }
187
188     /**
189       draw a line of pixels coming from the decompressor
190       if scaleafter > 1 we draw that many lines (numlines is the# lines in the buffer)
191       picturew is the resulting width of the picture
192     **/  
193     inline static void drawLine(Surface *sfc,enum Rotation rotate, unsigned char *cp,UINT scaleafter,UINT picturew,UINT pictureh, 
194         UINT xpos, UINT ypos, UINT outy, UINT linelen,UINT pixeloffset, UINT numlines, UINT fac) {
195       Colour c;
196       for (UINT x = 0; x < picturew; x++)
197       {
198         if (scaleafter > 1 ) {
199            //boxfilter scalefactor*scalefactor
200            //take 0...scalefactor pixels in x and y direction
201            for (int colornum=0;colornum<3;colornum++) {
202              UINT comp=0;
203              unsigned char * accp=cp;
204              for (UINT rows=0;rows<scaleafter;rows++) {
205                unsigned char * pp=accp;
206                for (UINT cols=0;cols<scaleafter;cols++) {
207                  comp+=(UINT)*pp;
208                  if (pp-accp < (int)linelen-3) pp+=3;
209                  }
210                if (rows < numlines) accp+=linelen;
211                }
212              comp=(comp*fac) >> 10;
213              if (colornum == 0) c.red=comp;
214              if (colornum == 1) c.green=comp;
215              if (colornum == 2) c.blue=comp;
216              cp++;
217            }
218           
219         }
220         else {
221           c.red = *cp;cp++;
222           c.green = *cp;cp++;
223           c.blue = *cp;cp++;
224         }
225         cp+=pixeloffset;
226         drawPixel(sfc,rotate,x, outy, picturew,pictureh,xpos,ypos,c);
227       }
228     }
229 #endif
230     //find my own surface and fill the area with my x and y offset within
231     Surface * getSurface(Region &a);
232
233     JpegReader *reader;
234     bool owningReader;
235     char errbuf[200];
236 };
237
238 #endif