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