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