Subversion Repositories eduke32

Rev

Rev 4922 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 Plagman 1
/**************************************************************************************************
2
KPLIB.C: Ken's Picture LIBrary written by Ken Silverman
1440 terminx 3
Copyright (c) 1998-2008 Ken Silverman
5 Plagman 4
Ken Silverman's official web site: http://advsys.net/ken
5
 
6
Features of KPLIB.C:
1440 terminx 7
        * Routines for decoding JPG/PNG/GIF/PCX/TGA/BMP/DDS/CEL.
5 Plagman 8
                See kpgetdim(), kprender(), and optional helper function: kpzload().
1440 terminx 9
        * Routines for reading files out of ZIP/GRP files. All ZIP/GRP functions start with "kz".
5 Plagman 10
        * Multi-platform support: Dos/Windows/Linux/Mac/etc..
11
        * Compact code, all in a single source file. Yeah, bad design on my part... but makes life
12
                  easier for everyone else - you simply add a single C file to your project, throw a few
13
                  externs in there, add the function calls, and you're done!
14
 
15
Brief history:
16
1998?: Wrote KPEG, a JPEG viewer for DOS
17
2000: Wrote KPNG, a PNG viewer for DOS
18
2001: Combined KPEG & KPNG, ported to Visual C, and made it into a library called KPLIB.C
1440 terminx 19
2002: Added support for TGA,GIF,CEL,ZIP
5 Plagman 20
2003: Added support for BMP
21
05/18/2004: Added support for 8&24 bit PCX
22
12/09/2005: Added support for progressive JPEG
194 terminx 23
01/05/2006: Added support for DDS
1440 terminx 24
07/28/2007: Added support for GRP (Build Engine archive)
5 Plagman 25
 
26
I offer this code to the community for free use - all I ask is that my name be included in the
27
credits.
28
 
29
-Ken S.
30
**************************************************************************************************/
31
 
512 Plagman 32
#include "compat.h"
4634 terminx 33
#include "kplib.h"
5 Plagman 34
#include <string.h>
35
#include <fcntl.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <stdio.h>
39
#include <stdlib.h>
4658 terminx 40
#include "pragmas.h"
5 Plagman 41
 
2630 helixhorne 42
#if defined(__POWERPC__) || defined(GEKKO)
5 Plagman 43
#define BIGENDIAN 1
44
#endif
45
 
46
#ifdef BIGENDIAN
1205 terminx 47
static uint32_t LSWAPIB(uint32_t a) { return(((a>>8)&0xff00)+((a&0xff00)<<8)+(a<<24)+(a>>24)); }
48
static uint16_t SSWAPIB(uint16_t a) { return((a>>8)+(a<<8)); }
5 Plagman 49
#define LSWAPIL(a) (a)
50
#define SSWAPIL(a) (a)
51
#else
52
#define LSWAPIB(a) (a)
53
#define SSWAPIB(a) (a)
1205 terminx 54
static uint32_t LSWAPIL(uint32_t a) { return(((a>>8)&0xff00)+((a&0xff00)<<8)+(a<<24)+(a>>24)); }
55
static uint16_t SSWAPIL(uint16_t a) { return((a>>8)+(a<<8)); }
5 Plagman 56
#endif
57
 
1479 terminx 58
#if !defined(_WIN32)
5 Plagman 59
#include <unistd.h>
60
#include <dirent.h>
1442 qbix79 61
typedef long long  __int64;
1440 terminx 62
static __inline int32_t _lrotl(int32_t i, int sh)
109 terminx 63
{ return((i>>(-sh))|(i<<sh)); }
2008 helixhorne 64
/*__inline*/ int32_t filelength(int h)
5 Plagman 65
{
109 terminx 66
    struct stat st;
67
    if (fstat(h,&st) < 0) return(-1);
68
    return(st.st_size);
5 Plagman 69
}
70
#define _fileno fileno
71
#else
72
#include <io.h>
73
#endif
74
 
1479 terminx 75
#if defined(_WIN32)
5 Plagman 76
#define WIN32_LEAN_AND_MEAN
77
#include <windows.h>
78
#endif
79
 
80
#ifndef O_BINARY
81
#define O_BINARY 0
82
#endif
83
#if !defined(max)
84
#define max(a,b) (((a) > (b)) ? (a) : (b))
85
#endif
86
#if !defined(min)
87
#define min(a,b) (((a) < (b)) ? (a) : (b))
88
#endif
89
 
4685 hendricks2 90
#if defined __clang__ && __clang_major__==3 && __clang_minor__==1
2292 helixhorne 91
// clang 3.1 SVN r149129, assertion failure with inline asm
92
# define NOASM 1
93
#endif
94
 
5 Plagman 95
#if defined(__GNUC__)
4513 hendricks2 96
#undef _inline
5 Plagman 97
#define _inline inline
98
#endif
99
 
109 terminx 100
//use GCC-specific extension to force symbol name to be something in particular to override underscoring.
5 Plagman 101
#if defined(__GNUC__) && defined(__i386__) && !defined(NOASM)
102
#define ASMNAME(x) asm(x)
103
#else
104
#define ASMNAME(x)
105
#endif
106
 
1440 terminx 107
static intptr_t frameplace;
4634 terminx 108
static int32_t bytesperline, xres, yres;
5 Plagman 109
 
1205 terminx 110
static const int32_t pow2mask[32] =
584 terminx 111
{
112
    0x00000000,0x00000001,0x00000003,0x00000007,
113
    0x0000000f,0x0000001f,0x0000003f,0x0000007f,
114
    0x000000ff,0x000001ff,0x000003ff,0x000007ff,
115
    0x00000fff,0x00001fff,0x00003fff,0x00007fff,
116
    0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
117
    0x000fffff,0x001fffff,0x003fffff,0x007fffff,
118
    0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff,
119
    0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,
120
};
1205 terminx 121
static const int32_t pow2long[32] =
584 terminx 122
{
123
    0x00000001,0x00000002,0x00000004,0x00000008,
124
    0x00000010,0x00000020,0x00000040,0x00000080,
125
    0x00000100,0x00000200,0x00000400,0x00000800,
126
    0x00001000,0x00002000,0x00004000,0x00008000,
127
    0x00010000,0x00020000,0x00040000,0x00080000,
128
    0x00100000,0x00200000,0x00400000,0x00800000,
129
    0x01000000,0x02000000,0x04000000,0x08000000,
3178 helixhorne 130
    0x10000000,0x20000000,0x40000000,(int32_t)0x80000000,
584 terminx 131
};
5 Plagman 132
 
109 terminx 133
//Hack for peekbits,getbits,suckbits (to prevent lots of duplicate code)
134
//   0: PNG: do 12-byte chunk_header removal hack
135
// !=0: ZIP: use 64K buffer (olinbuf)
1205 terminx 136
static int32_t zipfilmode;
4634 terminx 137
kzfilestate kzfs;
5 Plagman 138
 
4310 terminx 139
// GCC 4.6 LTO build fix
140
#ifdef USING_LTO
141
# define B_KPLIB_STATIC
142
#else
143
# define B_KPLIB_STATIC static
144
#endif
145
 
5 Plagman 146
//Initialized tables (can't be in union)
147
//jpg:                png:
148
//   crmul      16384    abstab10    4096
149
//   cbmul      16384    hxbit        472
150
//   dct         4608    pow2mask     128*
151
//   colclip     4096
152
//   colclipup8  4096
153
//   colclipup16 4096
154
//   unzig        256
155
//   pow2mask     128*
156
//   dcflagor      64
157
 
4310 terminx 158
B_KPLIB_STATIC int32_t ATTRIBUTE((used)) palcol[256] ASMNAME("palcol");
159
static int32_t paleng, bakcol, numhufblocks, zlibcompflags;
4634 terminx 160
static int8_t kcoltype, filtype, bitdepth;
5 Plagman 161
 
162
//============================ KPNGILIB begins ===============================
163
 
164
//07/31/2000: KPNG.C first ported to C from READPNG.BAS
165
//10/11/2000: KPNG.C split into 2 files: KPNG.C and PNGINLIB.C
166
//11/24/2000: Finished adding support for coltypes 4&6
167
//03/31/2001: Added support for Adam7-type interlaced images
168
//Currently, there is no support for:
169
//   * 16-bit color depth
170
//   * Some useless ancillary chunks, like: gAMA(gamma) & pHYs(aspect ratio)
171
 
109 terminx 172
//.PNG specific variables:
1205 terminx 173
static int32_t bakr = 0x80, bakg = 0x80, bakb = 0x80; //this used to be public...
174
static int32_t gslidew = 0, gslider = 0, xm, xmn[4], xr0, xr1, xplc, yplc;
737 qbix79 175
static intptr_t nfplace;
1205 terminx 176
static int32_t clen[320], cclen[19], bitpos, filt, xsiz, ysiz;
2286 helixhorne 177
int32_t xsizbpl, ixsiz, ixoff, iyoff, ixstp, iystp, intlac, nbpl;
178
B_KPLIB_STATIC int32_t ATTRIBUTE((used)) trnsrgb ASMNAME("trnsrgb");
1205 terminx 179
static int32_t ccind[19] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
180
static int32_t hxbit[59][2], ibuf0[288], nbuf0[32], ibuf1[32], nbuf1[32];
1440 terminx 181
static const uint8_t *filptr;
182
static uint8_t slidebuf[32768], opixbuf0[4], opixbuf1[4];
2286 helixhorne 183
static uint8_t pnginited = 0;
184
B_KPLIB_STATIC uint8_t olinbuf[131072] ASMNAME("olinbuf"); //WARNING:max xres is: 131072/bpp-1
185
B_KPLIB_STATIC int32_t ATTRIBUTE((used)) abstab10[1024] ASMNAME("abstab10");
5 Plagman 186
 
109 terminx 187
//Variables to speed up dynamic Huffman decoding:
5 Plagman 188
#define LOGQHUFSIZ0 9
189
#define LOGQHUFSIZ1 6
1205 terminx 190
static int32_t qhufval0[1<<LOGQHUFSIZ0], qhufval1[1<<LOGQHUFSIZ1];
1440 terminx 191
static uint8_t qhufbit0[1<<LOGQHUFSIZ0], qhufbit1[1<<LOGQHUFSIZ1];
5 Plagman 192
 
1454 terminx 193
#if defined(_MSC_VER) && !defined(NOASM)
5 Plagman 194
 
4315 hendricks2 195
#if defined(BIGENDIAN)
1205 terminx 196
static _inline uint32_t bswap(uint32_t a)
5 Plagman 197
{
109 terminx 198
    _asm
199
    {
200
        mov eax, a
201
        bswap eax
202
    }
5 Plagman 203
}
4315 hendricks2 204
#endif
5 Plagman 205
 
1205 terminx 206
static _inline int32_t bitrev(int32_t b, int32_t c)
5 Plagman 207
{
109 terminx 208
    _asm
209
    {
210
        mov edx, b
211
        mov ecx, c
212
        xor eax, eax
1762 terminx 213
        beg: shr edx, 1
109 terminx 214
        adc eax, eax
215
        sub ecx, 1
1452 terminx 216
        jnz short beg
109 terminx 217
    }
5 Plagman 218
}
219
 
194 terminx 220
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM)
5 Plagman 221
 
4315 hendricks2 222
#if defined(BIGENDIAN)
1205 terminx 223
static inline uint32_t bswap(uint32_t a)
5 Plagman 224
{
1762 terminx 225
    __asm__ __volatile__("bswap %0" : "+r"(a) : : "cc");
109 terminx 226
    return a;
5 Plagman 227
}
4315 hendricks2 228
#endif
5 Plagman 229
 
1205 terminx 230
static inline int32_t bitrev(int32_t b, int32_t c)
5 Plagman 231
{
1205 terminx 232
    int32_t a = 0;
584 terminx 233
    __asm__ __volatile__(
109 terminx 234
        "xorl %%eax, %%eax\n\t0:\n\tshrl $1, %%ebx\n\tadcl %%eax, %%eax\n\tsubl $1, %%ecx\n\tjnz 0b"
1762 terminx 235
        : "+a"(a), "+b"(b), "+c"(c) : : "cc");
109 terminx 236
    return a;
5 Plagman 237
}
238
 
239
#else
240
 
4315 hendricks2 241
#if defined(BIGENDIAN)
1205 terminx 242
static inline uint32_t bswap(uint32_t a)
194 terminx 243
{
244
    return(((a&0xff0000)>>8) + ((a&0xff00)<<8) + (a<<24) + (a>>24));
245
}
4315 hendricks2 246
#endif
5 Plagman 247
 
1205 terminx 248
static inline int32_t bitrev(int32_t b, int32_t c)
194 terminx 249
{
1205 terminx 250
    int32_t i, j;
1229 terminx 251
    for (i=1,j=0,c=(1<<c); i<c; i+=i) { j += j; if (b&i) j++; }
194 terminx 252
    return(j);
253
}
254
 
5 Plagman 255
#endif
256
 
1440 terminx 257
static uint8_t fakebuf[8], *nfilptr;
1205 terminx 258
static int32_t nbitpos;
584 terminx 259
static void suckbitsnextblock()
5 Plagman 260
{
4634 terminx 261
    if (zipfilmode)
109 terminx 262
    {
263
        //NOTE: should only read bytes inside compsize, not 64K!!! :/
4634 terminx 264
        int32_t n;
265
        *(int32_t *) &olinbuf[0] = *(int32_t *) &olinbuf[sizeof(olinbuf)-4];
266
        n = min((unsigned) (kzfs.compleng-kzfs.comptell), sizeof(olinbuf)-4);
267
        fread(&olinbuf[4], n, 1, kzfs.fil);
109 terminx 268
        kzfs.comptell += n;
269
        bitpos -= ((sizeof(olinbuf)-4)<<3);
4634 terminx 270
        return;
109 terminx 271
    }
4634 terminx 272
 
273
    if (nfilptr)
274
    {
275
        filptr = nfilptr; nfilptr = 0;
276
        bitpos -= ((nbitpos-4)<<3);
277
        return;
278
    }
279
    //if (n_from_suckbits < 4) will it crash?
280
 
281
    //|===|===|crc|lng|typ|===|===|
282
    //        \  fakebuf: /
283
    //          |===|===|
284
    //----x     O---x     O--------
285
    nbitpos = LSWAPIL(*(int32_t *)&filptr[8]);
286
    nfilptr = (uint8_t *)&filptr[nbitpos+12];
287
    *(int32_t *)&fakebuf[0] = *(int32_t *)&filptr[0]; //Copy last dword of IDAT chunk
4647 hendricks2 288
    if (*(int32_t *)&filptr[12] == (int32_t)LSWAPIB(0x54414449)) //Copy 1st dword of next IDAT chunk
4634 terminx 289
        *(int32_t *)&fakebuf[4] = *(int32_t *)&filptr[16];
290
    filptr = &fakebuf[4]; bitpos -= 32;
5 Plagman 291
}
292
 
1205 terminx 293
static _inline int32_t peekbits(int32_t n) { return((LSWAPIB(*(int32_t *)&filptr[bitpos>>3])>>(bitpos&7))&pow2mask[n]); }
4634 terminx 294
static _inline void suckbits(int32_t n) { bitpos += n; if (bitpos < 0) return; suckbitsnextblock(); }
1205 terminx 295
static _inline int32_t getbits(int32_t n) { int32_t i = peekbits(n); suckbits(n); return(i); }
5 Plagman 296
 
1205 terminx 297
static int32_t hufgetsym(int32_t *hitab, int32_t *hbmax)
5 Plagman 298
{
1205 terminx 299
    int32_t v, n;
5 Plagman 300
 
109 terminx 301
    v = n = 0;
584 terminx 302
    do { v = (v<<1)+getbits(1)+hbmax[n]-hbmax[n+1]; n++; }
303
    while (v >= 0);
109 terminx 304
    return(hitab[hbmax[n]+v]);
5 Plagman 305
}
306
 
109 terminx 307
//This did not result in a speed-up on P4-3.6Ghz (02/22/2005)
1205 terminx 308
//static int32_t hufgetsym_skipb (int32_t *hitab, int32_t *hbmax, int32_t n, int32_t addit)
5 Plagman 309
//{
1205 terminx 310
//   int32_t v;
5 Plagman 311
//
312
//   v = bitrev(getbits(n),n)+addit;
313
//   do { v = (v<<1)+getbits(1)+hbmax[n]-hbmax[n+1]; n++; } while (v >= 0);
314
//   return(hitab[hbmax[n]+v]);
315
//}
316
 
1440 terminx 317
static void qhufgencode(int32_t *hitab, int32_t *hbmax, int32_t *qhval, uint8_t *qhbit, int32_t numbits)
5 Plagman 318
{
1205 terminx 319
    int32_t i, j, k, n, r;
5 Plagman 320
 
109 terminx 321
    //r is the bit reverse of i. Ex: if: i = 1011100111, r = 1110011101
322
    i = r = 0;
1229 terminx 323
    for (n=1; n<=numbits; n++)
324
        for (k=hbmax[n-1]; k<hbmax[n]; k++)
325
            for (j=i+pow2mask[numbits-n]; i<=j; i++)
109 terminx 326
            {
327
                r = bitrev(i,numbits);
328
                qhval[r] = hitab[k];
1205 terminx 329
                qhbit[r] = (uint8_t)n;
109 terminx 330
            }
1229 terminx 331
    for (j=pow2mask[numbits]; i<=j; i++)
109 terminx 332
    {
333
        r = bitrev(i,numbits);
5 Plagman 334
 
109 terminx 335
        //k = 0;
336
        //for(n=0;n<numbits;n++)
337
        //   k = (k<<1) + ((r>>n)&1) + hbmax[n]-hbmax[n+1];
338
        //
339
        //n = numbits;
340
        //k = hbmax[n]-r;
341
        //
342
        //j = peekbits(LOGQHUFSIZ); i = qhufval[j]; j = qhufbit[j];
343
        //
344
        //i = j = 0;
345
        //do
346
        //{
347
        //   i = (i<<1)+getbits(1)+nbuf0[j]-nbuf0[j+1]; j++;
348
        //} while (i >= 0);
349
        //i = ibuf0[nbuf0[j]+i];
350
        //qhval[r] = k;
5 Plagman 351
 
109 terminx 352
        qhbit[r] = 0; //n-32;
353
    }
5 Plagman 354
 
109 terminx 355
    //   //hufgetsym_skipb related code:
356
    //for(k=n=0;n<numbits;n++) k = (k<<1)+hbmax[n]-hbmax[n+1];
357
    //return(k);
5 Plagman 358
}
359
 
109 terminx 360
//inbuf[inum] : Bit length of each symbol
361
//inum        : Number of indices
362
//hitab[inum] : Indices from size-ordered list to original symbol
363
//hbmax[0-31] : Highest index (+1) of n-bit symbol
4634 terminx 364
 
1205 terminx 365
static void hufgencode(int32_t *inbuf, int32_t inum, int32_t *hitab, int32_t *hbmax)
5 Plagman 366
{
4634 terminx 367
    int32_t i, tbuf[31], *tbufptr, *hbmaxptr;
5 Plagman 368
 
4634 terminx 369
    Bmemset(tbuf, 0, sizeof(tbuf));
1229 terminx 370
    for (i=inum-1; i>=0; i--) tbuf[inbuf[i]]++;
109 terminx 371
    tbuf[0] = hbmax[0] = 0; //Hack to remove symbols of length 0?
4634 terminx 372
    for (i=0; i<28; i += 4)
373
    {
374
        tbufptr = &tbuf[i];
375
        hbmaxptr = &hbmax[i];
376
 
377
        *(hbmaxptr+1) = *hbmaxptr     + *tbufptr;
378
        *(hbmaxptr+2) = *(hbmaxptr+1) + *(tbufptr+1);
379
        *(hbmaxptr+3) = *(hbmaxptr+2) + *(tbufptr+2);
380
        *(hbmaxptr+4) = *(hbmaxptr+3) + *(tbufptr+3);
381
    }
382
 
383
    tbufptr = &tbuf[i];
384
    hbmaxptr = &hbmax[i];
385
 
386
    *(hbmaxptr+1) = *hbmaxptr     + *tbufptr;
387
    *(hbmaxptr+2) = *(hbmaxptr+1) + *(tbufptr+1);
388
    *(hbmaxptr+3) = *(hbmaxptr+2) + *(tbufptr+2);
389
 
1229 terminx 390
    for (i=0; i<inum; i++) if (inbuf[i]) hitab[hbmax[inbuf[i]]++] = i;
5 Plagman 391
}
392
 
1205 terminx 393
static int32_t initpass()  //Interlaced images have 7 "passes", non-interlaced have 1
5 Plagman 394
{
1205 terminx 395
    int32_t i, j, k;
5 Plagman 396
 
109 terminx 397
    do
398
    {
399
        i = (intlac<<2);
400
        ixoff = ((0x04020100>>i)&15);
401
        iyoff = ((0x00402010>>i)&15);
402
        if (((ixoff >= xsiz) || (iyoff >= ysiz)) && (intlac >= 2)) { i = -1; intlac--; }
584 terminx 403
    }
404
    while (i < 0);
109 terminx 405
    j = ((0x33221100>>i)&15); ixstp = (1<<j);
406
    k = ((0x33322110>>i)&15); iystp = (1<<k);
5 Plagman 407
 
109 terminx 408
    //xsiz=12      0123456789ab
409
    //j=3,ixoff=0  0       1       ((12+(1<<3)-1 - 0)>>3) = 2
410
    //j=3,ixoff=4      2           ((12+(1<<3)-1 - 4)>>3) = 1
411
    //j=2,ixoff=2    3   4   5     ((12+(1<<2)-1 - 2)>>2) = 3
412
    //j=1,ixoff=1   6 7 8 9 a b    ((12+(1<<1)-1 - 1)>>1) = 6
413
    ixsiz = ((xsiz+ixstp-1-ixoff)>>j); //It's confusing! See the above example.
414
    nbpl = (bytesperline<<k);
5 Plagman 415
 
109 terminx 416
    //Initialize this to make filters fast:
4634 terminx 417
    xsizbpl = ((0x04021301>>(kcoltype<<2))&15)*ixsiz;
109 terminx 418
    switch (bitdepth)
419
    {
1440 terminx 420
    case 1: xsizbpl = ((xsizbpl+7)>>3); break;
421
    case 2: xsizbpl = ((xsizbpl+3)>>2); break;
422
    case 4: xsizbpl = ((xsizbpl+1)>>1); break;
109 terminx 423
    }
5 Plagman 424
 
1440 terminx 425
    Bmemset(olinbuf,0,(xsizbpl+1)*sizeof(olinbuf[0]));
1205 terminx 426
    *(int32_t *)&opixbuf0[0] = *(int32_t *)&opixbuf1[0] = 0;
4634 terminx 427
    xplc = xsizbpl; yplc = iyoff; xm = 0; filt = -1;
5 Plagman 428
 
4634 terminx 429
    i = ixoff; i = (((-(i>=0))|(ixstp-1))&i);
109 terminx 430
    k = (((-(yplc>=0))|(iystp-1))&yplc);
431
    nfplace = k*bytesperline + (i<<2) + frameplace;
5 Plagman 432
 
109 terminx 433
    //Precalculate x-clipping to screen borders (speeds up putbuf)
434
    //Equation: (0 <= xr <= ixsiz) && (0 <= xr*ixstp+globxoffs+ixoff <= xres)
4634 terminx 435
    xr0 = max((-ixoff+(1<<j)-1)>>j,0);
436
    xr1 = min((xres-ixoff+(1<<j)-1)>>j,ixsiz);
109 terminx 437
    xr0 = ixsiz-xr0;
438
    xr1 = ixsiz-xr1;
5 Plagman 439
 
4634 terminx 440
    if (kcoltype == 4) { xr0 = xr0*2;   xr1 = xr1*2;   }
441
    else if (kcoltype == 2) { xr0 = xr0*3-2; xr1 = xr1*3-2; }
442
    else if (kcoltype == 6) { xr0 = xr0*4-2; xr1 = xr1*4-2; }
109 terminx 443
    else
444
    {
331 terminx 445
        switch (bitdepth)
109 terminx 446
        {
1440 terminx 447
        case 1: xr0 += ((-ixsiz)&7)+7;
109 terminx 448
            xr1 += ((-ixsiz)&7)+7; break;
1440 terminx 449
        case 2: xr0 = ((xr0+((-ixsiz)&3)+3)<<1);
109 terminx 450
            xr1 = ((xr1+((-ixsiz)&3)+3)<<1); break;
1440 terminx 451
        case 4: xr0 = ((xr0+((-ixsiz)&1)+1)<<2);
109 terminx 452
            xr1 = ((xr1+((-ixsiz)&1)+1)<<2); break;
453
        }
454
    }
455
    ixstp <<= 2;
456
    return(0);
5 Plagman 457
}
458
 
1454 terminx 459
#if defined(_MSC_VER) && !defined(NOASM)
5 Plagman 460
 
1205 terminx 461
static _inline int32_t Paeth686(int32_t a, int32_t b, int32_t c)
5 Plagman 462
{
109 terminx 463
    _asm
464
    {
1440 terminx 465
        push ebx
466
        push esi
467
        push edi
109 terminx 468
        mov eax, a
469
        mov ebx, b
470
        mov ecx, c
471
        mov edx, ecx
472
        sub edx, eax
473
        sub edx, ebx
474
        lea edx, abstab10[edx*4+2048]
475
        mov esi, [ebx*4+edx]
476
        mov edi, [ecx*4+edx]
477
        cmp edi, esi
478
        cmovge edi, esi
479
        cmovge ecx, ebx
480
        cmp edi, [eax*4+edx]
481
        cmovl eax, ecx
1440 terminx 482
        pop edi
483
        pop esi
484
        pop ebx
109 terminx 485
    }
5 Plagman 486
}
487
 
1205 terminx 488
static _inline void rgbhlineasm(int32_t c, int32_t d, int32_t t, int32_t b)
5 Plagman 489
{
109 terminx 490
    _asm
491
    {
1440 terminx 492
        push ebx
493
        push edi
494
 
109 terminx 495
        mov ecx, c
496
        mov edx, d
497
        mov edi, t
498
        mov ebx, b
499
        sub ecx, edx
1452 terminx 500
        jle short endit
109 terminx 501
        add edx, offset olinbuf
584 terminx 502
        cmp dword ptr trnsrgb, 0
1452 terminx 503
        jz short begit2
1762 terminx 504
        begit:
584 terminx 505
        mov eax, dword ptr [ecx+edx]
506
        or eax, 0xff000000
507
        cmp eax, dword ptr trnsrgb
1452 terminx 508
        jne short skipit
584 terminx 509
        and eax, 0xffffff
1762 terminx 510
        skipit:
584 terminx 511
        sub ecx, 3
512
        mov [edi], eax
513
        lea edi, [edi+ebx]
1452 terminx 514
        jnz short begit
515
        jmp short endit
1762 terminx 516
        begit2:
584 terminx 517
        mov eax, dword ptr [ecx+edx]
518
        or eax, 0xff000000
519
        sub ecx, 3
520
        mov [edi], eax
521
        lea edi, [edi+ebx]
1452 terminx 522
        jnz short begit2
1762 terminx 523
        endit:
1440 terminx 524
        pop edi
525
        pop ebx
109 terminx 526
    }
584 terminx 527
}
5 Plagman 528
 
1205 terminx 529
static _inline void pal8hlineasm(int32_t c, int32_t d, int32_t t, int32_t b)
5 Plagman 530
{
109 terminx 531
    _asm
532
    {
533
        mov ecx, c
534
        mov edx, d
1440 terminx 535
        sub ecx, edx
1452 terminx 536
        jle short endit
1440 terminx 537
 
538
        push ebx
539
        push edi
109 terminx 540
        mov edi, t
541
        mov ebx, b
542
        add edx, offset olinbuf
1762 terminx 543
        begit:movzx eax, byte ptr [ecx+edx]
584 terminx 544
        mov eax, dword ptr palcol[eax*4]
545
        sub ecx, 1
546
        mov [edi], eax
547
        lea edi, [edi+ebx]
1452 terminx 548
        jnz short begit
1440 terminx 549
        pop edi
550
        pop ebx
1762 terminx 551
        endit:
109 terminx 552
    }
584 terminx 553
}
5 Plagman 554
 
194 terminx 555
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM)
5 Plagman 556
 
1205 terminx 557
static inline int32_t Paeth686(int32_t a, int32_t b, int32_t c)
5 Plagman 558
{
584 terminx 559
    __asm__ __volatile__(
1440 terminx 560
        "movl %%ecx, %%edx \n"
561
        "subl %%eax, %%edx \n"
562
        "subl %%ebx, %%edx \n"
563
        "leal (abstab10+2048)(,%%edx,4), %%edx \n"
564
        "movl (%%edx,%%ebx,4), %%esi \n"
565
        "movl (%%edx,%%ecx,4), %%edi \n"
566
        "cmpl %%esi, %%edi \n"
567
        "cmovgel %%esi, %%edi \n"
568
        "cmovgel %%ebx, %%ecx \n"
569
        "cmpl (%%edx,%%eax,4), %%edi \n"
570
        "cmovgel %%eax, %%ecx \n"
1762 terminx 571
        : "+c"(c) : "a"(a), "b"(b) : "edx","esi","edi","memory","cc"
572
    );
109 terminx 573
    return c;
5 Plagman 574
}
575
 
109 terminx 576
//Note: "cmove eax,?" may be faster than "jne ?:and eax,?" but who cares
1205 terminx 577
static inline void rgbhlineasm(int32_t c, int32_t d, int32_t t, int32_t b)
5 Plagman 578
{
584 terminx 579
    __asm__ __volatile__(
1440 terminx 580
        "subl %%edx, %%ecx \n"
581
        "jle 3f \n"
582
        "addl $olinbuf, %%edx \n"
583
        "cmpl $0, trnsrgb(,1) \n"
584
        "jz 2f \n"
585
        "0: movl (%%ecx,%%edx,1), %%eax \n"
586
        "orl $0xff000000, %%eax \n"
587
        "cmpl trnsrgb(,1), %%eax \n"
588
        "jne 1f \n"
589
        "andl $0xffffff, %%eax \n"
590
        "1: subl $3, %%ecx \n"
591
        "movl %%eax, (%%edi) \n"
592
        "leal (%%edi,%%ebx,1), %%edi \n"
593
        "jnz 0b \n"
594
        "jmp 3f \n"
595
        "2: movl (%%ecx,%%edx,1), %%eax \n"
596
        "orl $0xff000000, %%eax \n"
597
        "subl $3, %%ecx \n"
598
        "movl %%eax, (%%edi) \n"
599
        "leal (%%edi,%%ebx,1), %%edi \n"
600
        "jnz 2b \n"
601
        "3: \n"
1762 terminx 602
        : "+c"(c), "+d"(d), "+D"(t) : "b"(b) : "eax","memory","cc"
603
    );
5 Plagman 604
}
605
 
1205 terminx 606
static inline void pal8hlineasm(int32_t c, int32_t d, int32_t t, int32_t b)
5 Plagman 607
{
584 terminx 608
    __asm__ __volatile__(
1440 terminx 609
        "subl %%edx, %%ecx \n"
610
        "jle 1f \n"
611
        "addl $olinbuf, %%edx \n"
612
        "0: movzbl (%%ecx,%%edx,1), %%eax \n"
613
        "movl palcol(,%%eax,4), %%eax \n"
614
        "subl $1, %%ecx \n"
615
        "movl %%eax, (%%edi) \n"
616
        "leal (%%edi,%%ebx,1), %%edi \n"
617
        "jnz 0b \n"
618
        "1: \n"
1762 terminx 619
        : "+c"(c), "+d"(d), "+D"(t) : "b"(b) : "eax","memory","cc"
620
    );
5 Plagman 621
}
622
 
623
#else
624
 
5077 terminx 625
static inline int32_t Paeth686(int32_t const a, int32_t const b, int32_t c)
194 terminx 626
{
5077 terminx 627
    int32_t const * const ptr = &abstab10[(c - a) - (b - 512)];
628
    int32_t const esi = *(ptr + b);
629
    int32_t edi = *(ptr + c);
4634 terminx 630
    if (edi >= esi) edi = esi, c = b;
5077 terminx 631
    return (edi < *(ptr + a)) ? c : a;
194 terminx 632
}
5 Plagman 633
 
1205 terminx 634
static inline void rgbhlineasm(int32_t x, int32_t xr1, intptr_t p, int32_t ixstp)
194 terminx 635
{
1205 terminx 636
    int32_t i;
194 terminx 637
    if (!trnsrgb)
638
    {
1229 terminx 639
        for (; x>xr1; p+=ixstp,x-=3) *(int32_t *)p = (*(int32_t *)&olinbuf[x])|LSWAPIB(0xff000000);
194 terminx 640
        return;
641
    }
1229 terminx 642
    for (; x>xr1; p+=ixstp,x-=3)
194 terminx 643
    {
1205 terminx 644
        i = (*(int32_t *)&olinbuf[x])|LSWAPIB(0xff000000);
194 terminx 645
        if (i == trnsrgb) i &= LSWAPIB(0xffffff);
1205 terminx 646
        *(int32_t *)p = i;
194 terminx 647
    }
648
}
649
 
1205 terminx 650
static inline void pal8hlineasm(int32_t x, int32_t xr1, intptr_t p, int32_t ixstp)
194 terminx 651
{
1229 terminx 652
    for (; x>xr1; p+=ixstp,x--) *(int32_t *)p = palcol[olinbuf[x]];
194 terminx 653
}
654
 
5 Plagman 655
#endif
656
 
194 terminx 657
//Autodetect filter
658
//    /f0: 0000000...
659
//    /f1: 1111111...
660
//    /f2: 2222222...
661
//    /f3: 1333333...
662
//    /f3: 3333333...
663
//    /f4: 4444444...
664
//    /f5: 0142321...
1205 terminx 665
static int32_t filter1st, filterest;
1440 terminx 666
static void putbuf(const uint8_t *buf, int32_t leng)
5 Plagman 667
{
1205 terminx 668
    int32_t i, x;
737 qbix79 669
    intptr_t p;
5 Plagman 670
 
109 terminx 671
    if (filt < 0)
672
    {
673
        if (leng <= 0) return;
194 terminx 674
        filt = buf[0];
675
        if (filter1st < 0) filter1st = filt; else filterest |= (1<<filt);
109 terminx 676
        i = 1;
584 terminx 677
    }
678
    else i = 0;
5 Plagman 679
 
109 terminx 680
    while (i < leng)
681
    {
682
        x = i+xplc; if (x > leng) x = leng;
683
        switch (filt)
684
        {
685
        case 0:
5077 terminx 686
                while (i < x) { olinbuf[xplc--] = buf[i++]; }
109 terminx 687
            break;
688
        case 1:
1762 terminx 689
                while (i < x)
690
                {
5077 terminx 691
                    olinbuf[xplc--] = (uint8_t)(opixbuf1[xm] += buf[i++]);
692
                    xm = xmn[xm];
1762 terminx 693
                }
109 terminx 694
            break;
695
        case 2:
5077 terminx 696
                while (i < x) { olinbuf[xplc--] += (uint8_t)buf[i++]; }
109 terminx 697
            break;
698
        case 3:
1762 terminx 699
                while (i < x)
700
                {
5077 terminx 701
                    opixbuf1[xm] = olinbuf[xplc] = (uint8_t)(((opixbuf1[xm]+olinbuf[xplc])>>1)+buf[i++]);
702
                    xm = xmn[xm]; xplc--;
1762 terminx 703
                }
109 terminx 704
            break;
705
        case 4:
1762 terminx 706
                while (i < x)
707
                {
5077 terminx 708
                    opixbuf1[xm] = (uint8_t)(Paeth686(opixbuf1[xm],olinbuf[xplc],opixbuf0[xm])+buf[i++]);
1762 terminx 709
                    opixbuf0[xm] = olinbuf[xplc];
5077 terminx 710
                    olinbuf[xplc--] = opixbuf1[xm];
711
                    xm = xmn[xm];
1762 terminx 712
                }
109 terminx 713
            break;
714
        }
5 Plagman 715
 
109 terminx 716
        if (xplc > 0) return;
5 Plagman 717
 
109 terminx 718
        //Draw line!
1205 terminx 719
        if ((uint32_t)yplc < (uint32_t)yres)
109 terminx 720
        {
721
            x = xr0; p = nfplace;
4634 terminx 722
            switch (kcoltype)
109 terminx 723
            {
1440 terminx 724
            case 2: rgbhlineasm(x,xr1,p,ixstp); break;
109 terminx 725
            case 4:
1762 terminx 726
                    for (; x>xr1; p+=ixstp,x-=2)
727
                        *(int32_t *)p = (palcol[olinbuf[x]]&LSWAPIB(0xffffff))|LSWAPIL((int32_t)olinbuf[x-1]);
109 terminx 728
                break;
729
            case 6:
1762 terminx 730
                    for (; x>xr1; p+=ixstp,x-=4)
731
                    {
732
                        *(char *)(p) = olinbuf[x  ];   //B
733
                        *(char *)(p+1) = olinbuf[x+1]; //G
734
                        *(char *)(p+2) = olinbuf[x+2]; //R
735
                        *(char *)(p+3) = olinbuf[x-1]; //A
736
                    }
109 terminx 737
                break;
738
            default:
1762 terminx 739
                    switch (bitdepth)
740
                    {
741
                    case 1: for (; x>xr1; p+=ixstp,x--) *(int32_t *)p = palcol[olinbuf[x>>3]>>(x&7)]; break;
742
                    case 2: for (; x>xr1; p+=ixstp,x-=2) *(int32_t *)p = palcol[olinbuf[x>>3]>>(x&6)]; break;
743
                    case 4: for (; x>xr1; p+=ixstp,x-=4) *(int32_t *)p = palcol[olinbuf[x>>3]>>(x&4)]; break;
744
                    case 8: pal8hlineasm(x,xr1,p,ixstp); break; //for(;x>xr1;p+=ixstp,x-- ) *(int32_t *)p = palcol[olinbuf[x]]; break;
745
                    }
109 terminx 746
                break;
747
            }
748
            nfplace += nbpl;
749
        }
5 Plagman 750
 
1205 terminx 751
        *(int32_t *)&opixbuf0[0] = *(int32_t *)&opixbuf1[0] = 0;
109 terminx 752
        xplc = xsizbpl; yplc += iystp;
4634 terminx 753
        if ((intlac) && (yplc >= ysiz)) { intlac--; initpass(); }
194 terminx 754
        if (i < leng)
755
        {
756
            filt = buf[i++];
757
            if (filter1st < 0) filter1st = filt; else filterest |= (1<<filt);
584 terminx 758
        }
759
        else filt = -1;
109 terminx 760
    }
5 Plagman 761
}
762
 
763
static void initpngtables()
764
{
1205 terminx 765
    int32_t i, j, k;
5 Plagman 766
 
109 terminx 767
    //hxbit[0-58][0-1] is a combination of 4 different tables:
768
    //   1st parameter: [0-29] are distances, [30-58] are lengths
769
    //   2nd parameter: [0]: extra bits, [1]: base number
5 Plagman 770
 
109 terminx 771
    j = 1; k = 0;
1229 terminx 772
    for (i=0; i<30; i++)
109 terminx 773
    {
774
        hxbit[i][1] = j; j += (1<<k);
775
        hxbit[i][0] = k; k += ((i&1) && (i >= 2));
776
    }
777
    j = 3; k = 0;
1229 terminx 778
    for (i=257; i<285; i++)
109 terminx 779
    {
780
        hxbit[i+30-257][1] = j; j += (1<<k);
781
        hxbit[i+30-257][0] = k; k += ((!(i&3)) && (i >= 264));
782
    }
783
    hxbit[285+30-257][1] = 258; hxbit[285+30-257][0] = 0;
5 Plagman 784
 
4634 terminx 785
    for (i=0; i<512; i++) abstab10[512+i] = abstab10[512-i] = i;
5 Plagman 786
}
787
 
1205 terminx 788
static int32_t kpngrend(const char *kfilebuf, int32_t kfilength,
4634 terminx 789
                        intptr_t daframeplace, int32_t dabytesperline, int32_t daxres, int32_t dayres)
5 Plagman 790
{
1205 terminx 791
    int32_t i, j, k, bfinal, btype, hlit, hdist, leng;
792
    int32_t slidew, slider;
793
    //int32_t qhuf0v, qhuf1v;
5 Plagman 794
 
654 terminx 795
    UNREFERENCED_PARAMETER(kfilength);
796
 
109 terminx 797
    if (!pnginited) { pnginited = 1; initpngtables(); }
5 Plagman 798
 
4647 hendricks2 799
    if ((*(int32_t *)&kfilebuf[0] != (int32_t)LSWAPIB(0x474e5089)) || (*(int32_t *)&kfilebuf[4] != (int32_t)LSWAPIB(0x0a1a0a0d)))
109 terminx 800
        return(-1); //"Invalid PNG file signature"
1440 terminx 801
    filptr = (uint8_t *)&kfilebuf[8];
5 Plagman 802
 
194 terminx 803
    trnsrgb = 0; filter1st = -1; filterest = 0;
5 Plagman 804
 
109 terminx 805
    while (1)
806
    {
1205 terminx 807
        leng = LSWAPIL(*(int32_t *)&filptr[0]); i = *(int32_t *)&filptr[4];
109 terminx 808
        filptr = &filptr[8];
5 Plagman 809
 
4647 hendricks2 810
        if (i == (int32_t)LSWAPIB(0x52444849)) //IHDR (must be first)
109 terminx 811
        {
1205 terminx 812
            xsiz = LSWAPIL(*(int32_t *)&filptr[0]); if (xsiz <= 0) return(-1);
813
            ysiz = LSWAPIL(*(int32_t *)&filptr[4]); if (ysiz <= 0) return(-1);
109 terminx 814
            bitdepth = filptr[8]; if (!((1<<bitdepth)&0x116)) return(-1); //"Bit depth not supported"
4634 terminx 815
            kcoltype = filptr[9]; if (!((1<<kcoltype)&0x5d)) return(-1); //"Color type not supported"
109 terminx 816
            if (filptr[10]) return(-1); //"Only *flate is supported"
817
            if (filptr[11]) return(-1); //"Filter not supported"
818
            if (filptr[12] >= 2) return(-1); //"Unsupported interlace type"
819
            intlac = filptr[12]*7; //0=no interlace/1=Adam7 interlace
5 Plagman 820
 
109 terminx 821
            //Save code by making grayscale look like a palette color scheme
4634 terminx 822
            if ((!kcoltype) || (kcoltype == 4))
109 terminx 823
            {
4658 terminx 824
                j = 0xff000000; k = (tabledivide32(255, ((1<<bitdepth)-1)))*0x10101;
109 terminx 825
                paleng = (1<<bitdepth);
1229 terminx 826
                for (i=0; i<paleng; i++,j+=k) palcol[i] = LSWAPIB(j);
109 terminx 827
            }
828
        }
4647 hendricks2 829
        else if (i == (int32_t)LSWAPIB(0x45544c50)) //PLTE (must be before IDAT)
109 terminx 830
        {
4661 terminx 831
            paleng = leng/3;
1229 terminx 832
            for (i=paleng-1; i>=0; i--) palcol[i] = LSWAPIB((LSWAPIL(*(int32_t *)&filptr[i*3])>>8)|0xff000000);
109 terminx 833
        }
4647 hendricks2 834
        else if (i == (int32_t)LSWAPIB(0x44474b62)) //bKGD (must be after PLTE and before IDAT)
109 terminx 835
        {
4634 terminx 836
            switch (kcoltype)
109 terminx 837
            {
1440 terminx 838
            case 0: case 4:
4658 terminx 839
                        bakcol = (((int32_t)filptr[0]<<8)+(int32_t)filptr[1])*tabledivide32(255, ((1<<bitdepth)-1));
109 terminx 840
                bakcol = bakcol*0x10101+0xff000000; break;
1440 terminx 841
            case 2: case 6:
1762 terminx 842
                        if (bitdepth == 8)
843
                            { bakcol = (((int32_t)filptr[1])<<16)+(((int32_t)filptr[3])<<8)+((int32_t)filptr[5])+0xff000000; }
844
                        else
845
                        {
846
                            for (i=0,bakcol=0xff000000; i<3; i++)
4658 terminx 847
                                bakcol += tabledivide32(((((int32_t)filptr[i<<1])<<8)+((int32_t)filptr[(i<<1)+1])), 257)<<(16-(i<<3));
1762 terminx 848
                        }
109 terminx 849
                break;
850
            case 3:
1762 terminx 851
                    bakcol = palcol[filptr[0]]; break;
109 terminx 852
            }
853
            bakr = ((bakcol>>16)&255);
854
            bakg = ((bakcol>>8)&255);
855
            bakb = (bakcol&255);
856
            bakcol = LSWAPIB(bakcol);
857
        }
4647 hendricks2 858
        else if (i == (int32_t)LSWAPIB(0x534e5274)) //tRNS (must be after PLTE and before IDAT)
109 terminx 859
        {
4634 terminx 860
            switch (kcoltype)
109 terminx 861
            {
862
            case 0:
1762 terminx 863
                    if (bitdepth <= 8)
864
                        palcol[(int32_t)filptr[1]] &= LSWAPIB(0xffffff);
109 terminx 865
                //else {} // /c0 /d16 not yet supported
866
                break;
867
            case 2:
1762 terminx 868
                    if (bitdepth == 8)
869
                        { trnsrgb = LSWAPIB((((int32_t)filptr[1])<<16)+(((int32_t)filptr[3])<<8)+((int32_t)filptr[5])+0xff000000); }
109 terminx 870
                //else {} //WARNING: PNG docs say: MUST compare all 48 bits :(
871
                break;
872
            case 3:
1762 terminx 873
                    for (i=min(leng,paleng)-1; i>=0; i--)
874
                        palcol[i] &= LSWAPIB((((int32_t)filptr[i])<<24)|0xffffff);
109 terminx 875
                break;
1440 terminx 876
            default:;
4680 terminx 877
                EDUKE32_UNREACHABLE_SECTION();
109 terminx 878
            }
879
        }
4647 hendricks2 880
        else if (i == (int32_t)LSWAPIB(0x54414449)) { break; }  //IDAT
5 Plagman 881
 
1205 terminx 882
        filptr = &filptr[leng+4]; //crc = LSWAPIL(*(int32_t *)&filptr[-4]);
109 terminx 883
    }
5 Plagman 884
 
109 terminx 885
    //Initialize this for the getbits() function
886
    zipfilmode = 0;
887
    filptr = &filptr[leng-4]; bitpos = -((leng-4)<<3); nfilptr = 0;
888
    //if (leng < 4) will it crash?
5 Plagman 889
 
109 terminx 890
    frameplace = daframeplace;
891
    bytesperline = dabytesperline;
892
    xres = daxres;
893
    yres = dayres;
4634 terminx 894
    switch (kcoltype)
109 terminx 895
    {
1440 terminx 896
    case 4: xmn[0] = 1; xmn[1] = 0; break;
897
    case 2: xmn[0] = 1; xmn[1] = 2; xmn[2] = 0; break;
898
    case 6: xmn[0] = 1; xmn[1] = 2; xmn[2] = 3; xmn[3] = 0; break;
899
    default: xmn[0] = 0; break;
109 terminx 900
    }
901
    switch (bitdepth)
902
    {
1440 terminx 903
    case 1: for (i=2; i<256; i++) palcol[i] = palcol[i&1]; break;
904
    case 2: for (i=4; i<256; i++) palcol[i] = palcol[i&3]; break;
905
    case 4: for (i=16; i<256; i++) palcol[i] = palcol[i&15]; break;
109 terminx 906
    }
5 Plagman 907
 
109 terminx 908
    //coltype: bitdepth:  format:
909
    //  0     1,2,4,8,16  I
910
    //  2           8,16  RGB
911
    //  3     1,2,4,8     P
912
    //  4           8,16  IA
913
    //  6           8,16  RGBA
4634 terminx 914
    xsizbpl = ((0x04021301>>(kcoltype<<2))&15)*xsiz;
109 terminx 915
    switch (bitdepth)
916
    {
1440 terminx 917
    case 1: xsizbpl = ((xsizbpl+7)>>3); break;
918
    case 2: xsizbpl = ((xsizbpl+3)>>2); break;
919
    case 4: xsizbpl = ((xsizbpl+1)>>1); break;
109 terminx 920
    }
921
    //Tests to see if xsiz > allocated space in olinbuf
922
    //Note: xsizbpl gets re-written inside initpass()
923
    if ((xsizbpl+1)*sizeof(olinbuf[0]) > sizeof(olinbuf)) return(-1);
5 Plagman 924
 
109 terminx 925
    initpass();
5 Plagman 926
 
109 terminx 927
    slidew = 0; slider = 16384;
194 terminx 928
    zlibcompflags = getbits(16); //Actually 2 fields: 8:compmethflags, 8:addflagscheck
109 terminx 929
    do
930
    {
931
        bfinal = getbits(1); btype = getbits(2);
932
        if (btype == 0)
933
        {
934
            //Raw (uncompressed)
935
            suckbits((-bitpos)&7);  //Synchronize to start of next byte
936
            i = getbits(16); if ((getbits(16)^i) != 0xffff) return(-1);
1229 terminx 937
            for (; i; i--)
109 terminx 938
            {
939
                if (slidew >= slider)
940
                {
941
                    putbuf(&slidebuf[(slider-16384)&32767],16384); slider += 16384;
194 terminx 942
                    if ((yplc >= yres) && (intlac < 2)) goto kpngrend_goodret;
109 terminx 943
                }
1205 terminx 944
                slidebuf[(slidew++)&32767] = (uint8_t)getbits(8);
109 terminx 945
            }
946
            continue;
947
        }
948
        if (btype == 3) continue;
5 Plagman 949
 
109 terminx 950
        if (btype == 1) //Fixed Huffman
951
        {
952
            hlit = 288; hdist = 32; i = 0;
1229 terminx 953
            for (; i<144; i++) clen[i] = 8; //Fixed bit sizes (literals)
954
            for (; i<256; i++) clen[i] = 9; //Fixed bit sizes (literals)
955
            for (; i<280; i++) clen[i] = 7; //Fixed bit sizes (EOI,lengths)
956
            for (; i<288; i++) clen[i] = 8; //Fixed bit sizes (lengths)
957
            for (; i<320; i++) clen[i] = 5; //Fixed bit sizes (distances)
109 terminx 958
        }
959
        else  //Dynamic Huffman
960
        {
1440 terminx 961
            numhufblocks++;
109 terminx 962
            hlit = getbits(5)+257; hdist = getbits(5)+1; j = getbits(4)+4;
1229 terminx 963
            for (i=0; i<j; i++) cclen[ccind[i]] = getbits(3);
964
            for (; i<19; i++) cclen[ccind[i]] = 0;
109 terminx 965
            hufgencode(cclen,19,ibuf0,nbuf0);
5 Plagman 966
 
109 terminx 967
            j = 0; k = hlit+hdist;
968
            while (j < k)
969
            {
970
                i = hufgetsym(ibuf0,nbuf0);
971
                if (i < 16) { clen[j++] = i; continue; }
972
                if (i == 16)
1229 terminx 973
                    { for (i=getbits(2)+3; i; i--) { clen[j] = clen[j-1]; j++; } }
109 terminx 974
                else
975
                {
976
                    if (i == 17) i = getbits(3)+3; else i = getbits(7)+11;
1229 terminx 977
                    for (; i; i--) clen[j++] = 0;
109 terminx 978
                }
979
            }
980
        }
5 Plagman 981
 
109 terminx 982
        hufgencode(clen,hlit,ibuf0,nbuf0);
983
        //qhuf0v = //hufgetsym_skipb related code
984
        qhufgencode(ibuf0,nbuf0,qhufval0,qhufbit0,LOGQHUFSIZ0);
5 Plagman 985
 
109 terminx 986
        hufgencode(&clen[hlit],hdist,ibuf1,nbuf1);
987
        //qhuf1v = //hufgetsym_skipb related code
988
        qhufgencode(ibuf1,nbuf1,qhufval1,qhufbit1,LOGQHUFSIZ1);
5 Plagman 989
 
109 terminx 990
        while (1)
991
        {
992
            if (slidew >= slider)
993
            {
994
                putbuf(&slidebuf[(slider-16384)&32767],16384); slider += 16384;
194 terminx 995
                if ((yplc >= yres) && (intlac < 2)) goto kpngrend_goodret;
109 terminx 996
            }
5 Plagman 997
 
109 terminx 998
            k = peekbits(LOGQHUFSIZ0);
1205 terminx 999
            if (qhufbit0[k]) { i = qhufval0[k]; suckbits((int32_t)qhufbit0[k]); }
584 terminx 1000
            else i = hufgetsym(ibuf0,nbuf0);
109 terminx 1001
            //else i = hufgetsym_skipb(ibuf0,nbuf0,LOGQHUFSIZ0,qhuf0v); //hufgetsym_skipb related code
5 Plagman 1002
 
1205 terminx 1003
            if (i < 256) { slidebuf[(slidew++)&32767] = (uint8_t)i; continue; }
109 terminx 1004
            if (i == 256) break;
1005
            i = getbits(hxbit[i+30-257][0]) + hxbit[i+30-257][1];
5 Plagman 1006
 
109 terminx 1007
            k = peekbits(LOGQHUFSIZ1);
1205 terminx 1008
            if (qhufbit1[k]) { j = qhufval1[k]; suckbits((int32_t)qhufbit1[k]); }
584 terminx 1009
            else j = hufgetsym(ibuf1,nbuf1);
109 terminx 1010
            //else j = hufgetsym_skipb(ibuf1,nbuf1,LOGQHUFSIZ1,qhuf1v); //hufgetsym_skipb related code
5 Plagman 1011
 
109 terminx 1012
            j = getbits(hxbit[j][0]) + hxbit[j][1];
584 terminx 1013
            i += slidew; do { slidebuf[slidew&32767] = slidebuf[(slidew-j)&32767]; slidew++; }
1014
            while (slidew < i);
109 terminx 1015
        }
584 terminx 1016
    }
1017
    while (!bfinal);
5 Plagman 1018
 
109 terminx 1019
    slider -= 16384;
1020
    if (!((slider^slidew)&32768))
1021
        putbuf(&slidebuf[slider&32767],slidew-slider);
1022
    else
1023
    {
1024
        putbuf(&slidebuf[slider&32767],(-slider)&32767);
1025
        putbuf(slidebuf,slidew&32767);
1026
    }
194 terminx 1027
 
4634 terminx 1028
kpngrend_goodret:
1440 terminx 1029
    if (!(filterest&~(1<<filter1st))) filtype = (int8_t)filter1st;
194 terminx 1030
    else if ((filter1st == 1) && (!(filterest&~(1<<3)))) filtype = 3;
1031
    else filtype = 5;
4634 terminx 1032
    if (kcoltype == 4) paleng = 0; //For /c4, palcol/paleng used as LUT for "*0x10101": alpha is invalid!
109 terminx 1033
    return(0);
5 Plagman 1034
}
1035
 
1036
//============================= KPNGILIB ends ================================
1037
//============================ KPEGILIB begins ===============================
1038
 
109 terminx 1039
//11/01/2000: This code was originally from KPEG.C
1040
//   All non 32-bit color drawing was removed
1041
//   "Motion" JPG code was removed
1042
//   A lot of parameters were added to kpeg() for library usage
1205 terminx 1043
static int32_t kpeginited = 0;
1044
static int32_t clipxdim, clipydim;
5 Plagman 1045
 
1205 terminx 1046
static int32_t hufmaxatbit[8][20], hufvalatbit[8][20], hufcnt[8];
1440 terminx 1047
static uint8_t hufnumatbit[8][20], huftable[8][256];
1205 terminx 1048
static int32_t hufquickval[8][1024], hufquickbits[8][1024], hufquickcnt[8];
1049
static int32_t quantab[4][64], dct[12][64], lastdc[4], unzig[64], zigit[64]; //dct:10=MAX (says spec);+2 for hacks
1440 terminx 1050
static uint8_t gnumcomponents, dcflagor[64];
1205 terminx 1051
static int32_t gcompid[4], gcomphsamp[4], gcompvsamp[4], gcompquantab[4], gcomphsampshift[4], gcompvsampshift[4];
1052
static int32_t lnumcomponents, lcompid[4], lcompdc[4], lcompac[4], lcomphsamp[4], lcompvsamp[4], lcompquantab[4];
1053
static int32_t lcomphvsamp0, lcomphsampshift0, lcompvsampshift0;
1054
static int32_t colclip[1024], colclipup8[1024], colclipup16[1024];
1440 terminx 1055
/*static uint8_t pow2char[8] = {1,2,4,8,16,32,64,128};*/
5 Plagman 1056
 
1454 terminx 1057
#if defined(_MSC_VER) && !defined(NOASM)
5 Plagman 1058
 
1205 terminx 1059
static _inline int32_t mulshr24(int32_t a, int32_t d)
5 Plagman 1060
{
109 terminx 1061
    _asm
1062
    {
1063
        mov eax, a
1064
        imul d
1065
        shrd eax, edx, 24
1066
    }
5 Plagman 1067
}
1068
 
1205 terminx 1069
static _inline int32_t mulshr32(int32_t a, int32_t d)
5 Plagman 1070
{
109 terminx 1071
    _asm
1072
    {
1073
        mov eax, a
1074
        imul d
1075
        mov eax, edx
1076
    }
5 Plagman 1077
}
1078
 
194 terminx 1079
#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM)
5 Plagman 1080
 
1081
#define mulshr24(a,d) \
1205 terminx 1082
        ({ int32_t __a=(a), __d=(d); \
5 Plagman 1083
                __asm__ __volatile__ ("imull %%edx; shrdl $24, %%edx, %%eax" \
1084
                : "+a" (__a), "+d" (__d) : : "cc"); \
1085
         __a; })
1086
 
1087
#define mulshr32(a,d) \
1205 terminx 1088
        ({ int32_t __a=(a), __d=(d); \
5 Plagman 1089
                __asm__ __volatile__ ("imull %%edx" \
1090
                : "+a" (__a), "+d" (__d) : : "cc"); \
1091
         __d; })
1092
 
1093
#else
1094
 
1205 terminx 1095
static inline int32_t mulshr24(int32_t a, int32_t b)
194 terminx 1096
{
1205 terminx 1097
    return((int32_t)((((__int64)a)*((__int64)b))>>24));
194 terminx 1098
}
5 Plagman 1099
 
1205 terminx 1100
static inline int32_t mulshr32(int32_t a, int32_t b)
194 terminx 1101
{
1205 terminx 1102
    return((int32_t)((((__int64)a)*((__int64)b))>>32));
194 terminx 1103
}
1104
 
5 Plagman 1105
#endif
1106
 
1205 terminx 1107
static int32_t cosqr16[8] =    //cosqr16[i] = ((cos(PI*i/16)*sqrt(2))<<24);
1762 terminx 1108
{23726566,23270667,21920489,19727919,16777216,13181774,9079764,4628823};
4101 hendricks2 1109
static int32_t crmul[4096], cbmul[4096];
5 Plagman 1110
 
584 terminx 1111
static void initkpeg()
5 Plagman 1112
{
4101 hendricks2 1113
    int32_t i, j, x, y;
5 Plagman 1114
 
109 terminx 1115
    x = 0;  //Back & forth diagonal pattern (aligning bytes for best compression)
1229 terminx 1116
    for (i=0; i<16; i+=2)
109 terminx 1117
    {
1229 terminx 1118
        for (y=8-1; y>=0; y--)
109 terminx 1119
            if ((unsigned)(i-y) < (unsigned)8) unzig[x++] = (y<<3)+i-y;
1229 terminx 1120
        for (y=0; y<8; y++)
109 terminx 1121
            if ((unsigned)(i+1-y) < (unsigned)8) unzig[x++] = (y<<3)+i+1-y;
1122
    }
1229 terminx 1123
    for (i=64-1; i>=0; i--) zigit[unzig[i]] = i;
1124
    for (i=64-1; i>=0; i--) dcflagor[i] = (uint8_t)(1<<(unzig[i]>>3));
5 Plagman 1125
 
1229 terminx 1126
    for (i=0; i<128; i++) colclip[i] = i+128;
1127
    for (i=128; i<512; i++) colclip[i] = 255;
1128
    for (i=512; i<896; i++) colclip[i] = 0;
1129
    for (i=896; i<1024; i++) colclip[i] = i-896;
1130
    for (i=0; i<1024; i++)
109 terminx 1131
    {
1132
        colclipup8[i] = (colclip[i]<<8);
1133
        colclipup16[i] = (colclip[i]<<16)+0xff000000; //Hack: set alphas to 255
1134
    }
5 Plagman 1135
#if defined(BIGENDIAN)
1229 terminx 1136
    for (i=0; i<1024; i++)
109 terminx 1137
    {
1138
        colclip[i] = bswap(colclip[i]);
1139
        colclipup8[i] = bswap(colclipup8[i]);
1140
        colclipup16[i] = bswap(colclipup16[i]);
1141
    }
5 Plagman 1142
#endif
1143
 
1229 terminx 1144
    for (i=0; i<2048; i++)
109 terminx 1145
    {
4101 hendricks2 1146
        j = i-1024;
1147
        crmul[(i<<1)+0] = j*1470104; //1.402*1048576
1148
        crmul[(i<<1)+1] = j*-748830; //-0.71414*1048576
1149
        cbmul[(i<<1)+0] = j*-360857; //-0.34414*1048576
1150
        cbmul[(i<<1)+1] = j*1858077; //1.772*1048576
109 terminx 1151
    }
5 Plagman 1152
 
1440 terminx 1153
    Bmemset((void *)&dct[10][0],0,64*2*sizeof(dct[0][0]));
5 Plagman 1154
}
1155
 
1205 terminx 1156
static void huffgetval(int32_t index, int32_t curbits, int32_t num, int32_t *daval, int32_t *dabits)
5 Plagman 1157
{
1205 terminx 1158
    int32_t b, v, pow2, *hmax;
5 Plagman 1159
 
109 terminx 1160
    hmax = &hufmaxatbit[index][0];
1161
    pow2 = pow2long[curbits-1];
1162
    if (num&pow2) v = 1; else v = 0;
1229 terminx 1163
    for (b=1; b<=16; b++)
109 terminx 1164
    {
1165
        if (v < hmax[b])
1166
        {
1167
            *dabits = b;
1168
            *daval = huftable[index][hufvalatbit[index][b]+v];
1169
            return;
1170
        }
1171
        pow2 >>= 1; v <<= 1;
1172
        if (num&pow2) v++;
1173
    }
1174
    *dabits = 16; *daval = 0;
5 Plagman 1175
}
1176
 
1440 terminx 1177
static void invdct8x8(int32_t *dc, uint8_t dcflag)
5 Plagman 1178
{
331 terminx 1179
#define SQRT2 23726566   //(sqrt(2))<<24
1180
#define C182 31000253    //(cos(PI/8)*2)<<24
1181
#define C18S22 43840978  //(cos(PI/8)*sqrt(2)*2)<<24
1182
#define C38S22 18159528  //(cos(PI*3/8)*sqrt(2)*2)<<24
1205 terminx 1183
    int32_t *edc, t0, t1, t2, t3, t4, t5, t6, t7;
5 Plagman 1184
 
109 terminx 1185
    edc = dc+64;
1186
    do
1187
    {
1188
        if (dcflag&1) //pow2char[z])
1189
        {
1190
            t3 = dc[2] + dc[6];
1191
            t2 = (mulshr32(dc[2]-dc[6],SQRT2<<6)<<2) - t3;
1192
            t4 = dc[0] + dc[4]; t5 = dc[0] - dc[4];
1193
            t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2;
1194
            t4 = (mulshr32(dc[5]-dc[3]+dc[1]-dc[7],C182<<6)<<2);
1195
            t7 = dc[1] + dc[7] + dc[5] + dc[3];
1196
            t6 = (mulshr32(dc[3]-dc[5],C18S22<<5)<<3) + t4 - t7;
1197
            t5 = (mulshr32(dc[1]+dc[7]-dc[5]-dc[3],SQRT2<<6)<<2) - t6;
1198
            t4 = (mulshr32(dc[1]-dc[7],C38S22<<6)<<2) - t4 + t5;
1199
            dc[0] = t0+t7; dc[7] = t0-t7; dc[1] = t1+t6; dc[6] = t1-t6;
1200
            dc[2] = t2+t5; dc[5] = t2-t5; dc[4] = t3+t4; dc[3] = t3-t4;
1201
        }
1202
        dc += 8; dcflag >>= 1;
584 terminx 1203
    }
1204
    while (dc < edc);
109 terminx 1205
    dc -= 32; edc -= 24;
1206
    do
1207
    {
1208
        t3 = dc[2*8-32] + dc[6*8-32];
1209
        t2 = (mulshr32(dc[2*8-32]-dc[6*8-32],SQRT2<<6)<<2) - t3;
1210
        t4 = dc[0*8-32] + dc[4*8-32]; t5 = dc[0*8-32] - dc[4*8-32];
1211
        t0 = t4+t3; t3 = t4-t3; t1 = t5+t2; t2 = t5-t2;
1212
        t4 = (mulshr32(dc[5*8-32]-dc[3*8-32]+dc[1*8-32]-dc[7*8-32],C182<<6)<<2);
1213
        t7 = dc[1*8-32] + dc[7*8-32] + dc[5*8-32] + dc[3*8-32];
1214
        t6 = (mulshr32(dc[3*8-32]-dc[5*8-32],C18S22<<5)<<3) + t4 - t7;
1215
        t5 = (mulshr32(dc[1*8-32]+dc[7*8-32]-dc[5*8-32]-dc[3*8-32],SQRT2<<6)<<2) - t6;
1216
        t4 = (mulshr32(dc[1*8-32]-dc[7*8-32],C38S22<<6)<<2) - t4 + t5;
1217
        dc[0*8-32] = t0+t7; dc[7*8-32] = t0-t7; dc[1*8-32] = t1+t6; dc[6*8-32] = t1-t6;
1218
        dc[2*8-32] = t2+t5; dc[5*8-32] = t2-t5; dc[4*8-32] = t3+t4; dc[3*8-32] = t3-t4;
1219
        dc++;
584 terminx 1220
    }
1221
    while (dc < edc);
5 Plagman 1222
}
1223
 
1440 terminx 1224
static void yrbrend(int32_t x, int32_t y, int32_t *ldct)
5 Plagman 1225
{
1205 terminx 1226
    int32_t i, j, ox, oy, xx, yy, xxx, yyy, xxxend, yyyend, yv, cr = 0, cb = 0, *odc, *dc, *dc2;
1440 terminx 1227
    intptr_t p, pp;
5 Plagman 1228
 
1440 terminx 1229
    odc = ldct; dc2 = &ldct[10<<6];
1229 terminx 1230
    for (yy=0; yy<(lcompvsamp[0]<<3); yy+=8)
109 terminx 1231
    {
4634 terminx 1232
        oy = y+yy; if ((unsigned)oy >= (unsigned)clipydim) { odc += (lcomphsamp[0]<<6); continue; }
1233
        pp = oy*bytesperline + ((x)<<2) + frameplace;
1229 terminx 1234
        for (xx=0; xx<(lcomphsamp[0]<<3); xx+=8,odc+=64)
109 terminx 1235
        {
4634 terminx 1236
            ox = x+xx; if ((unsigned)ox >= (unsigned)clipxdim) continue;
109 terminx 1237
            p = pp+(xx<<2);
1238
            dc = odc;
1440 terminx 1239
            if (lnumcomponents > 1) dc2 = &ldct[(lcomphvsamp0<<6)+((yy>>lcompvsampshift0)<<3)+(xx>>lcomphsampshift0)];
109 terminx 1240
            xxxend = min(clipxdim-ox,8);
1241
            yyyend = min(clipydim-oy,8);
1242
            if ((lcomphsamp[0] == 1) && (xxxend == 8))
1243
            {
1229 terminx 1244
                for (yyy=0; yyy<yyyend; yyy++)
109 terminx 1245
                {
1229 terminx 1246
                    for (xxx=0; xxx<8; xxx++)
109 terminx 1247
                    {
1248
                        yv = dc[xxx];
1440 terminx 1249
                        cr = (dc2[xxx+64]>>(20-1))&~1;
1250
                        cb = (dc2[xxx   ]>>(20-1))&~1;
1205 terminx 1251
                        ((int32_t *)p)[xxx] = colclipup16[(unsigned)(yv+crmul[cr+2048])>>22]+
1229 terminx 1252
                                              colclipup8[(unsigned)(yv+crmul[cr+2049]+cbmul[cb+2048])>>22]+
1253
                                              colclip[(unsigned)(yv+cbmul[cb+2049])>>22];
109 terminx 1254
                    }
1255
                    p += bytesperline;
1256
                    dc += 8;
1257
                    if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
1258
                }
1259
            }
1260
            else if ((lcomphsamp[0] == 2) && (xxxend == 8))
1261
            {
1229 terminx 1262
                for (yyy=0; yyy<yyyend; yyy++)
109 terminx 1263
                {
1229 terminx 1264
                    for (xxx=0; xxx<8; xxx+=2)
109 terminx 1265
                    {
1266
                        yv = dc[xxx];
1440 terminx 1267
                        cr = (dc2[(xxx>>1)+64]>>(20-1))&~1;
1268
                        cb = (dc2[(xxx>>1)]>>(20-1))&~1;
109 terminx 1269
                        i = crmul[cr+2049]+cbmul[cb+2048];
1270
                        cr = crmul[cr+2048];
1271
                        cb = cbmul[cb+2049];
1205 terminx 1272
                        ((int32_t *)p)[xxx] = colclipup16[(unsigned)(yv+cr)>>22]+
1229 terminx 1273
                                              colclipup8[(unsigned)(yv+ i)>>22]+
1274
                                              colclip[(unsigned)(yv+cb)>>22];
109 terminx 1275
                        yv = dc[xxx+1];
1205 terminx 1276
                        ((int32_t *)p)[xxx+1] = colclipup16[(unsigned)(yv+cr)>>22]+
1229 terminx 1277
                                                colclipup8[(unsigned)(yv+ i)>>22]+
1278
                                                colclip[(unsigned)(yv+cb)>>22];
109 terminx 1279
                    }
1280
                    p += bytesperline;
1281
                    dc += 8;
1282
                    if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
1283
                }
1284
            }
1285
            else
1286
            {
1229 terminx 1287
                for (yyy=0; yyy<yyyend; yyy++)
109 terminx 1288
                {
1289
                    i = 0; j = 1;
1229 terminx 1290
                    for (xxx=0; xxx<xxxend; xxx++)
109 terminx 1291
                    {
1292
                        yv = dc[xxx];
1293
                        j--;
1294
                        if (!j)
1295
                        {
1296
                            j = lcomphsamp[0];
1440 terminx 1297
                            cr = (dc2[i+64]>>(20-1))&~1;
1298
                            cb = (dc2[i   ]>>(20-1))&~1;
109 terminx 1299
                            i++;
1300
                        }
1205 terminx 1301
                        ((int32_t *)p)[xxx] = colclipup16[(unsigned)(yv+crmul[cr+2048])>>22]+
1229 terminx 1302
                                              colclipup8[(unsigned)(yv+crmul[cr+2049]+cbmul[cb+2048])>>22]+
1303
                                              colclip[(unsigned)(yv+cbmul[cb+2049])>>22];
109 terminx 1304
                    }
1305
                    p += bytesperline;
1306
                    dc += 8;
1307
                    if (!((yyy+1)&(lcompvsamp[0]-1))) dc2 += 8;
1308
                }
1309
            }
1310
        }
1311
    }
5 Plagman 1312
}
1440 terminx 1313
void (*kplib_yrbrend_func)(int32_t,int32_t,int32_t *) = yrbrend;
5 Plagman 1314
 
4597 terminx 1315
#define KPEG_GETBITS(curbits, minbits, num, kfileptr, kfileend)\
1316
        while (curbits < minbits)\
1317
        {\
1318
                ch = *kfileptr++; num = (num<<8)+((int)ch); curbits += 8;\
1319
                if (ch == 255) { kfileptr++; if (kfileptr >= kfileend) { num <<= 8; curbits += 8; /*Hack to prevent read overrun on valid JPG by stuffing extra byte*/ } }\
1320
        }
1321
 
1322
 
1205 terminx 1323
static int32_t kpegrend(const char *kfilebuf, int32_t kfilength,
4634 terminx 1324
                        intptr_t daframeplace, int32_t dabytesperline, int32_t daxres, int32_t dayres)
5 Plagman 1325
{
2537 hendricks2 1326
    int32_t i, j, v, leng = 0, xdim = 0, ydim = 0, index, prec, restartcnt, restartinterval;
1440 terminx 1327
    int32_t x, y, z, xx, yy, zz, *dc = NULL, num, curbits, c, daval, dabits, *hqval, *hqbits, hqcnt, *quanptr = NULL;
1205 terminx 1328
    int32_t passcnt = 0, ghsampmax = 0, gvsampmax = 0, glhsampmax = 0, glvsampmax = 0, glhstep, glvstep;
2228 hendricks2 1329
    int32_t eobrun, Ss, Se, Ah, Al, Alut[2], dctx[12], dcty[12], ldctx[12], /* ldcty[12], */ lshx[4], lshy[4];
1440 terminx 1330
    int16_t *dctbuf = 0, *dctptr[12], *ldctptr[12], *dcs = NULL;
1331
    uint8_t ch, marker, dcflag;
4597 terminx 1332
    const uint8_t *kfileptr, *kfileend;
5 Plagman 1333
 
109 terminx 1334
    if (!kpeginited) { kpeginited = 1; initkpeg(); }
5 Plagman 1335
 
1440 terminx 1336
    kfileptr = (uint8_t *)kfilebuf;
4597 terminx 1337
    kfileend = &kfileptr[kfilength];
5 Plagman 1338
 
1205 terminx 1339
    if (*(uint16_t *)kfileptr == SSWAPIB(0xd8ff)) kfileptr += 2;
109 terminx 1340
    else return(-1); //"%s is not a JPEG file\n",filename
5 Plagman 1341
 
109 terminx 1342
    restartinterval = 0;
1229 terminx 1343
    for (i=0; i<4; i++) lastdc[i] = 0;
1344
    for (i=0; i<8; i++) hufcnt[i] = 0;
5 Plagman 1345
 
4634 terminx 1346
    kcoltype = 0; bitdepth = 8; //For PNGOUT
109 terminx 1347
    do
1348
    {
1349
        ch = *kfileptr++; if (ch != 255) continue;
584 terminx 1350
        do { marker = *kfileptr++; }
1351
        while (marker == 255);
109 terminx 1352
        if (marker != 0xd9) //Don't read past end of buffer
1353
        {
737 qbix79 1354
            leng = ((intptr_t)kfileptr[0]<<8)+(intptr_t)kfileptr[1]-2;
109 terminx 1355
            kfileptr += 2;
1356
        }
1205 terminx 1357
        //printf("fileoffs=%08x, marker=%02x,leng=%d",((int32_t)kfileptr)-((int32_t)kfilebuf)-2,marker,leng);
331 terminx 1358
        switch (marker)
109 terminx 1359
        {
1440 terminx 1360
        case 0xc0: case 0xc1: case 0xc2:
1762 terminx 1361
                        //processit!
1362
                        kfileptr++; //numbits = *kfileptr++;
5 Plagman 1363
 
1205 terminx 1364
            ydim = SSWAPIL(*(uint16_t *)&kfileptr[0]);
1365
            xdim = SSWAPIL(*(uint16_t *)&kfileptr[2]);
1440 terminx 1366
            //printf("%s: %ld / %ld = %ld\n",filename,xdim*ydim*3,kfilength,(xdim*ydim*3)/kfilength);
5 Plagman 1367
 
109 terminx 1368
            frameplace = daframeplace;
1369
            bytesperline = dabytesperline;
1370
            xres = daxres;
1371
            yres = dayres;
1372
            gnumcomponents = kfileptr[4];
1373
            kfileptr += 5;
1374
            ghsampmax = gvsampmax = glhsampmax = glvsampmax = 0;
1229 terminx 1375
            for (z=0; z<gnumcomponents; z++)
109 terminx 1376
            {
1377
                gcompid[z] = kfileptr[0];
1378
                gcomphsamp[z] = (kfileptr[1]>>4);
1379
                gcompvsamp[z] = (kfileptr[1]&15);
1380
                gcompquantab[z] = kfileptr[2];
1229 terminx 1381
                for (i=0; i<8; i++) if (gcomphsamp[z] == pow2long[i]) { gcomphsampshift[z] = i; break; }
1382
                for (i=0; i<8; i++) if (gcompvsamp[z] == pow2long[i]) { gcompvsampshift[z] = i; break; }
109 terminx 1383
                if (gcomphsamp[z] > ghsampmax) { ghsampmax = gcomphsamp[z]; glhsampmax = gcomphsampshift[z]; }
1384
                if (gcompvsamp[z] > gvsampmax) { gvsampmax = gcompvsamp[z]; glvsampmax = gcompvsampshift[z]; }
1385
                kfileptr += 3;
1386
            }
5 Plagman 1387
 
109 terminx 1388
            break;
1389
        case 0xc4:  //Huffman table
1762 terminx 1390
                do
1391
                {
1392
                    ch = *kfileptr++; leng--;
1393
                    if (ch >= 16) { index = ch-12; }
1394
                    else { index = ch; }
1395
                    Bmemcpy((void *)&hufnumatbit[index][1],(void *)kfileptr,16); kfileptr += 16;
1396
                    leng -= 16;
5 Plagman 1397
 
1762 terminx 1398
                    v = 0; hufcnt[index] = 0;
1399
                    hufquickcnt[index] = 0;
1400
                    for (i=1; i<=16; i++)
1401
                    {
1402
                        hufmaxatbit[index][i] = v+hufnumatbit[index][i];
1403
                        hufvalatbit[index][i] = hufcnt[index]-v;
1404
                        Bmemcpy((void *)&huftable[index][hufcnt[index]],(void *)kfileptr,(int32_t)hufnumatbit[index][i]);
1405
                        if (i <= 10)
1406
                            for (c=0; c<hufnumatbit[index][i]; c++)
1407
                                for (j=(1<<(10-i)); j>0; j--)
1408
                                {
1409
                                    hufquickval[index][hufquickcnt[index]] = huftable[index][hufcnt[index]+c];
1410
                                    hufquickbits[index][hufquickcnt[index]] = i;
1411
                                    hufquickcnt[index]++;
1412
                                }
1413
                        kfileptr += hufnumatbit[index][i];
1414
                        leng -= hufnumatbit[index][i];
1415
                        hufcnt[index] += hufnumatbit[index][i];
1416
                        v = ((v+hufnumatbit[index][i])<<1);
1417
                    }
1418
 
109 terminx 1419
                }
1762 terminx 1420
                while (leng > 0);
109 terminx 1421
            break;
1422
        case 0xdb:
1762 terminx 1423
                do
109 terminx 1424
                {
1762 terminx 1425
                    ch = *kfileptr++; leng--;
1426
                    index = (ch&15);
1427
                    prec = (ch>>4);
1428
                    for (z=0; z<64; z++)
1429
                    {
1430
                        v = (int32_t)(*kfileptr++);
1431
                        if (prec) v = (v<<8)+((int32_t)(*kfileptr++));
1432
                        v <<= 19;
1433
                        if (unzig[z]&7) v = mulshr24(v,cosqr16[unzig[z]&7 ]);
1434
                        if (unzig[z]>>3) v = mulshr24(v,cosqr16[unzig[z]>>3]);
1435
                        quantab[index][unzig[z]] = v;
1436
                    }
1437
                    leng -= 64;
1438
                    if (prec) leng -= 64;
109 terminx 1439
                }
1762 terminx 1440
                while (leng > 0);
109 terminx 1441
            break;
1442
        case 0xdd:
1762 terminx 1443
                restartinterval = SSWAPIL(*(uint16_t *)&kfileptr[0]);
109 terminx 1444
            kfileptr += leng;
1445
            break;
1446
        case 0xda:
1762 terminx 1447
                if ((xdim <= 0) || (ydim <= 0)) { if (dctbuf) Bfree(dctbuf); return(-1); }
5 Plagman 1448
 
1527 terminx 1449
            lnumcomponents = (int32_t)(*kfileptr++); if (!lnumcomponents) { if (dctbuf) Bfree(dctbuf); return(-1); }
4634 terminx 1450
            if (lnumcomponents > 1) kcoltype = 2;
1229 terminx 1451
            for (z=0; z<lnumcomponents; z++)
109 terminx 1452
            {
1453
                lcompid[z] = kfileptr[0];
1454
                lcompdc[z] = (kfileptr[1]>>4);
1455
                lcompac[z] = (kfileptr[1]&15);
1456
                kfileptr += 2;
1457
            }
5 Plagman 1458
 
109 terminx 1459
            Ss = kfileptr[0];
1460
            Se = kfileptr[1];
1461
            Ah = (kfileptr[2]>>4);
1462
            Al = (kfileptr[2]&15);
1463
            kfileptr += 3;
1464
            //printf("passcnt=%d, Ss=%d, Se=%d, Ah=%d, Al=%d\n",passcnt,Ss,Se,Ah,Al);
5 Plagman 1465
 
109 terminx 1466
            if ((!passcnt) && ((Ss) || (Se != 63) || (Ah) || (Al)))
1467
            {
1229 terminx 1468
                for (z=zz=0; z<gnumcomponents; z++)
109 terminx 1469
                {
1470
                    dctx[z] = ((xdim+(ghsampmax<<3)-1)>>(glhsampmax+3)) << gcomphsampshift[z];
1471
                    dcty[z] = ((ydim+(gvsampmax<<3)-1)>>(glvsampmax+3)) << gcompvsampshift[z];
1472
                    zz += dctx[z]*dcty[z];
1473
                }
1205 terminx 1474
                z = zz*64*sizeof(int16_t);
1527 terminx 1475
                dctbuf = (int16_t *)Bmalloc(z); if (!dctbuf) return(-1);
1440 terminx 1476
                Bmemset(dctbuf,0,z);
1229 terminx 1477
                for (z=zz=0; z<gnumcomponents; z++) { dctptr[z] = &dctbuf[zz*64]; zz += dctx[z]*dcty[z]; }
109 terminx 1478
            }
5 Plagman 1479
 
109 terminx 1480
            glhstep = glvstep = 0x7fffffff;
1229 terminx 1481
            for (z=0; z<lnumcomponents; z++)
1482
                for (zz=0; zz<gnumcomponents; zz++)
109 terminx 1483
                    if (lcompid[z] == gcompid[zz])
1484
                    {
1485
                        ldctptr[z] = dctptr[zz];
1486
                        ldctx[z] = dctx[zz];
2228 hendricks2 1487
                       // ldcty[z] = dcty[zz];
109 terminx 1488
                        lcomphsamp[z] = gcomphsamp[zz];
1489
                        lcompvsamp[z] = gcompvsamp[zz];
1490
                        lcompquantab[z] = gcompquantab[zz];
1491
                        if (!z)
1492
                        {
1493
                            lcomphsampshift0 = gcomphsampshift[zz];
1494
                            lcompvsampshift0 = gcompvsampshift[zz];
1495
                        }
1496
                        lshx[z] = glhsampmax-gcomphsampshift[zz]+3;
1497
                        lshy[z] = glvsampmax-gcompvsampshift[zz]+3;
1498
                        if (gcomphsampshift[zz] < glhstep) glhstep = gcomphsampshift[zz];
1499
                        if (gcompvsampshift[zz] < glvstep) glvstep = gcompvsampshift[zz];
1500
                    }
1501
            glhstep = (ghsampmax>>glhstep); lcomphsamp[0] = min(lcomphsamp[0],glhstep); glhstep <<= 3;
1502
            glvstep = (gvsampmax>>glvstep); lcompvsamp[0] = min(lcompvsamp[0],glvstep); glvstep <<= 3;
1503
            lcomphvsamp0 = lcomphsamp[0]*lcompvsamp[0];
5 Plagman 1504
 
4634 terminx 1505
            clipxdim = min(xdim,xres);
1506
            clipydim = min(ydim,yres);
5 Plagman 1507
 
109 terminx 1508
            Alut[0] = (1<<Al); Alut[1] = -Alut[0];
5 Plagman 1509
 
109 terminx 1510
            restartcnt = restartinterval; eobrun = 0; marker = 0xd0;
1511
            num = 0; curbits = 0;
1229 terminx 1512
            for (y=0; y<ydim; y+=glvstep)
1513
                for (x=0; x<xdim; x+=glhstep)
109 terminx 1514
                {
1440 terminx 1515
                    if (kfileptr-4-(uint8_t *)kfilebuf >= kfilength) goto kpegrend_break2; //rest of file is missing!
5 Plagman 1516
 
109 terminx 1517
                    if (!dctbuf) dc = dct[0];
1229 terminx 1518
                    for (c=0; c<lnumcomponents; c++)
109 terminx 1519
                    {
1520
                        hqval = &hufquickval[lcompac[c]+4][0];
1521
                        hqbits = &hufquickbits[lcompac[c]+4][0];
1522
                        hqcnt = hufquickcnt[lcompac[c]+4];
1523
                        if (!dctbuf) quanptr = &quantab[lcompquantab[c]][0];
1229 terminx 1524
                        for (yy=0; yy<(lcompvsamp[c]<<3); yy+=8)
1525
                            for (xx=0; xx<(lcomphsamp[c]<<3); xx+=8)
1762 terminx 1526
                            {
1527
                                //NOTE: Might help to split this code into firstime vs. refinement (!Ah vs. Ah!=0)
5 Plagman 1528
 
109 terminx 1529
                                if (dctbuf) dcs = &ldctptr[c][(((y+yy)>>lshy[c])*ldctx[c] + ((x+xx)>>lshx[c]))<<6];
5 Plagman 1530
 
109 terminx 1531
                                //Get DC
1532
                                if (!Ss)
1533
                                {
4597 terminx 1534
                                    KPEG_GETBITS(curbits, 16, num, kfileptr, kfileend);
109 terminx 1535
                                    if (!Ah)
1536
                                    {
1537
                                        i = ((num>>(curbits-10))&1023);
1538
                                        if (i < hufquickcnt[lcompdc[c]])
584 terminx 1539
                                            { daval = hufquickval[lcompdc[c]][i]; curbits -= hufquickbits[lcompdc[c]][i]; }
109 terminx 1540
                                        else { huffgetval(lcompdc[c],curbits,num,&daval,&dabits); curbits -= dabits; }
5 Plagman 1541
 
109 terminx 1542
                                        if (daval)
1543
                                        {
4597 terminx 1544
                                            KPEG_GETBITS(curbits, daval, num, kfileptr, kfileend);
109 terminx 1545
                                            curbits -= daval; v = ((unsigned)num >> curbits) & pow2mask[daval];
1546
                                            if (v <= pow2mask[daval-1]) v -= pow2mask[daval];
1547
                                            lastdc[c] += v;
1548
                                        }
1205 terminx 1549
                                        if (!dctbuf) dc[0] = lastdc[c]; else dcs[0] = (int16_t)(lastdc[c]<<Al);
109 terminx 1550
                                    }
1205 terminx 1551
                                    else if (num&(pow2long[--curbits])) dcs[0] |= ((int16_t)Alut[0]);
109 terminx 1552
                                }
5 Plagman 1553
 
109 terminx 1554
                                //Get AC
1440 terminx 1555
                                if (!dctbuf) Bmemset((void *)&dc[1],0,63*4);
109 terminx 1556
                                z = max(Ss,1); dcflag = 1;
1557
                                if (eobrun <= 0)
1558
                                {
1229 terminx 1559
                                    for (; z<=Se; z++)
109 terminx 1560
                                    {
4597 terminx 1561
                                        KPEG_GETBITS(curbits, 16, num, kfileptr, kfileend);
109 terminx 1562
                                        i = ((num>>(curbits-10))&1023);
1563
                                        if (i < hqcnt)
584 terminx 1564
                                            { daval = hqval[i]; curbits -= hqbits[i]; }
109 terminx 1565
                                        else { huffgetval(lcompac[c]+4,curbits,num,&daval,&dabits); curbits -= dabits; }
5 Plagman 1566
 
109 terminx 1567
                                        zz = (daval>>4); daval &= 15;
1568
                                        if (daval)
1569
                                        {
1570
                                            if (Ah)
1571
                                            {
4597 terminx 1572
                                                KPEG_GETBITS(curbits, 8, num, kfileptr, kfileend);
109 terminx 1573
                                                if (num&(pow2long[--curbits])) daval = Alut[0]; else daval = Alut[1];
1574
                                            }
1575
                                        }
1576
                                        else if (zz < 15)
1577
                                        {
1578
                                            eobrun = pow2long[zz];
1579
                                            if (zz)
1580
                                            {
4597 terminx 1581
                                                KPEG_GETBITS(curbits, zz, num, kfileptr, kfileend);
109 terminx 1582
                                                curbits -= zz; eobrun += ((unsigned)num >> curbits) & pow2mask[zz];
1583
                                            }
1584
                                            if (!Ah) eobrun--;
1585
                                            break;
1586
                                        }
1587
                                        if (Ah)
1588
                                        {
1589
                                            do
1590
                                            {
1591
                                                if (dcs[z])
1592
                                                {
4597 terminx 1593
                                                    KPEG_GETBITS(curbits, 8, num, kfileptr, kfileend);
1440 terminx 1594
                                                    if (num&(pow2long[--curbits])) dcs[z] += (int16_t)Alut[dcs[z] < 0];
584 terminx 1595
                                                }
1596
                                                else if (--zz < 0) break;
109 terminx 1597
                                                z++;
584 terminx 1598
                                            }
1599
                                            while (z <= Se);
1440 terminx 1600
                                            if (daval) dcs[z] = (int16_t)daval;
109 terminx 1601
                                        }
1602
                                        else
1603
                                        {
1604
                                            z += zz; if (z > Se) break;
5 Plagman 1605
 
4597 terminx 1606
                                            KPEG_GETBITS(curbits, daval, num, kfileptr, kfileend);
109 terminx 1607
                                            curbits -= daval; v = ((unsigned)num >> curbits) & pow2mask[daval];
2164 helixhorne 1608
                                            if (daval>=1 /* FIXME ? */ && v <= pow2mask[daval-1]) v -= pow2mask[daval];
109 terminx 1609
                                            dcflag |= dcflagor[z];
1205 terminx 1610
                                            if (!dctbuf) dc[unzig[z]] = v; else dcs[z] = (int16_t)(v<<Al);
109 terminx 1611
                                        }
1612
                                    }
584 terminx 1613
                                }
1614
                                else if (!Ah) eobrun--;
109 terminx 1615
                                if ((Ah) && (eobrun > 0))
1616
                                {
1617
                                    eobrun--;
1229 terminx 1618
                                    for (; z<=Se; z++)
109 terminx 1619
                                    {
1620
                                        if (!dcs[z]) continue;
4597 terminx 1621
                                        KPEG_GETBITS(curbits, 8, num, kfileptr, kfileend);
1205 terminx 1622
                                        if (num&(pow2long[--curbits])) dcs[z] += ((int16_t)Alut[dcs[z] < 0]);
109 terminx 1623
                                    }
1624
                                }
5 Plagman 1625
 
109 terminx 1626
                                if (!dctbuf)
1627
                                {
1229 terminx 1628
                                    for (z=64-1; z>=0; z--) dc[z] *= quanptr[z];
109 terminx 1629
                                    invdct8x8(dc,dcflag); dc += 64;
1630
                                }
1631
                            }
1632
                    }
5 Plagman 1633
 
1440 terminx 1634
                    if (!dctbuf) kplib_yrbrend_func(x,y,&dct[0][0]);
5 Plagman 1635
 
109 terminx 1636
                    restartcnt--;
1637
                    if (!restartcnt)
1638
                    {
1639
                        kfileptr += 1-(curbits>>3); curbits = 0;
1640
                        if ((kfileptr[-2] != 255) || (kfileptr[-1] != marker)) kfileptr--;
1641
                        marker++; if (marker >= 0xd8) marker = 0xd0;
1642
                        restartcnt = restartinterval;
1229 terminx 1643
                        for (i=0; i<4; i++) lastdc[i] = 0;
109 terminx 1644
                        eobrun = 0;
1645
                    }
1646
                }
1762 terminx 1647
            kpegrend_break2:;
109 terminx 1648
            if (!dctbuf) return(0);
1649
            passcnt++; kfileptr -= ((curbits>>3)+1); break;
1440 terminx 1650
        case 0xd9: break;
1651
        default: kfileptr += leng; break;
109 terminx 1652
        }
584 terminx 1653
    }
1440 terminx 1654
    while (kfileptr-(uint8_t *)kfilebuf < kfilength);
5 Plagman 1655
 
109 terminx 1656
    if (!dctbuf) return(0);
5 Plagman 1657
 
109 terminx 1658
    lnumcomponents = gnumcomponents;
1229 terminx 1659
    for (i=0; i<gnumcomponents; i++)
109 terminx 1660
    {
1661
        lcomphsamp[i] = gcomphsamp[i]; gcomphsamp[i] <<= 3;
1662
        lcompvsamp[i] = gcompvsamp[i]; gcompvsamp[i] <<= 3;
1663
        lshx[i] = glhsampmax-gcomphsampshift[i]+3;
1664
        lshy[i] = glvsampmax-gcompvsampshift[i]+3;
1665
    }
1666
    lcomphsampshift0 = gcomphsampshift[0];
1667
    lcompvsampshift0 = gcompvsampshift[0];
1668
    lcomphvsamp0 = (lcomphsamp[0]<<lcompvsampshift0);
1229 terminx 1669
    for (y=0; y<ydim; y+=gcompvsamp[0])
1670
        for (x=0; x<xdim; x+=gcomphsamp[0])
109 terminx 1671
        {
1672
            dc = dct[0];
1229 terminx 1673
            for (c=0; c<gnumcomponents; c++)
1674
                for (yy=0; yy<gcompvsamp[c]; yy+=8)
1675
                    for (xx=0; xx<gcomphsamp[c]; xx+=8,dc+=64)
109 terminx 1676
                    {
1677
                        dcs = &dctptr[c][(((y+yy)>>lshy[c])*dctx[c] + ((x+xx)>>lshx[c]))<<6];
1678
                        quanptr = &quantab[gcompquantab[c]][0];
1229 terminx 1679
                        for (z=0; z<64; z++) dc[z] = ((int32_t)dcs[zigit[z]])*quanptr[z];
1440 terminx 1680
                        invdct8x8(dc,0xff);
109 terminx 1681
                    }
1440 terminx 1682
            kplib_yrbrend_func(x,y,&dct[0][0]);
109 terminx 1683
        }
5 Plagman 1684
 
1527 terminx 1685
    Bfree(dctbuf); return(0);
5 Plagman 1686
}
1687
 
1688
//==============================  KPEGILIB ends ==============================
1689
//================================ GIF begins ================================
1690
 
1440 terminx 1691
static uint8_t suffix[4100], filbuffer[768], tempstack[4096];
1205 terminx 1692
static int32_t prefix[4100];
5 Plagman 1693
 
1205 terminx 1694
static int32_t kgifrend(const char *kfilebuf, int32_t kfilelength,
4634 terminx 1695
                        intptr_t daframeplace, int32_t dabytesperline, int32_t daxres, int32_t dayres)
5 Plagman 1696
{
1205 terminx 1697
    int32_t i, x, y, xsiz, ysiz, yinc, xend, xspan, yspan, currstr, numbitgoal;
4670 terminx 1698
    int32_t lzcols, dat, blocklen, bitcnt, xoff, transcol;
1440 terminx 1699
    intptr_t yoff;
109 terminx 1700
    char numbits, startnumbits, chunkind, ilacefirst;
1502 terminx 1701
    const uint8_t *ptr, *cptr = NULL;
4634 terminx 1702
    int32_t daglobxoffs = 0, daglobyoffs = 0;
1440 terminx 1703
 
654 terminx 1704
    UNREFERENCED_PARAMETER(kfilelength);
1705
 
4634 terminx 1706
    kcoltype = 3; bitdepth = 8; //For PNGOUT
5 Plagman 1707
 
1490 terminx 1708
    if ((kfilebuf[0] != 'G') || (kfilebuf[1] != 'I') || (kfilebuf[2] != 'F')) return(-1);
109 terminx 1709
    paleng = (1<<((kfilebuf[10]&7)+1));
1440 terminx 1710
    ptr = (uint8_t *)&kfilebuf[13];
584 terminx 1711
    if (kfilebuf[10]&128) { cptr = ptr; ptr += paleng*3; }
109 terminx 1712
    transcol = -1;
1713
    while ((chunkind = *ptr++) == '!')
1762 terminx 1714
    {
1715
        //! 0xf9 leng flags ? ? transcol
1205 terminx 1716
        if (ptr[0] == 0xf9) { if (ptr[2]&1) transcol = (int32_t)(((uint8_t)ptr[5])); }
109 terminx 1717
        ptr++;
584 terminx 1718
        do { i = *ptr++; ptr += i; }
1719
        while (i);
109 terminx 1720
    }
1721
    if (chunkind != ',') return(-1);
5 Plagman 1722
 
1205 terminx 1723
    xoff = SSWAPIB(*(uint16_t *)&ptr[0]);
1724
    yoff = SSWAPIB(*(uint16_t *)&ptr[2]);
1725
    xspan = SSWAPIB(*(uint16_t *)&ptr[4]);
1726
    yspan = SSWAPIB(*(uint16_t *)&ptr[6]); ptr += 9;
584 terminx 1727
    if (ptr[-1]&64) { yinc = 8; ilacefirst = 1; }
109 terminx 1728
    else { yinc = 1; ilacefirst = 0; }
1729
    if (ptr[-1]&128)
1730
    {
1731
        paleng = (1<<((ptr[-1]&7)+1));
1732
        cptr = ptr; ptr += paleng*3;
1733
    }
5 Plagman 1734
 
1229 terminx 1735
    for (i=0; i<paleng; i++)
1205 terminx 1736
        palcol[i] = LSWAPIB((((int32_t)cptr[i*3])<<16) + (((int32_t)cptr[i*3+1])<<8) + ((int32_t)cptr[i*3+2]) + 0xff000000);
1229 terminx 1737
    for (; i<256; i++) palcol[i] = LSWAPIB(0xff000000);
109 terminx 1738
    if (transcol >= 0) palcol[transcol] &= LSWAPIB(~0xff000000);
5 Plagman 1739
 
109 terminx 1740
    //Handle GIF files with different logical&image sizes or non-0 offsets (added 05/15/2004)
1205 terminx 1741
    xsiz = SSWAPIB(*(uint16_t *)&kfilebuf[6]);
1742
    ysiz = SSWAPIB(*(uint16_t *)&kfilebuf[8]);
109 terminx 1743
    if ((xoff != 0) || (yoff != 0) || (xsiz != xspan) || (ysiz != yspan))
1744
    {
1745
        daglobxoffs += xoff; //Offset bitmap image by extra amount
1746
        daglobyoffs += yoff;
1747
    }
5 Plagman 1748
 
109 terminx 1749
    xspan += daglobxoffs;
1750
    yspan += daglobyoffs;  //UGLY HACK
1751
    y = daglobyoffs;
1205 terminx 1752
    if ((uint32_t)y < (uint32_t)dayres)
584 terminx 1753
        { yoff = y*dabytesperline+daframeplace; x = daglobxoffs; xend = xspan; }
109 terminx 1754
    else
584 terminx 1755
        { x = daglobxoffs+0x80000000; xend = xspan+0x80000000; }
5 Plagman 1756
 
1205 terminx 1757
    lzcols = (1<<(*ptr)); startnumbits = (uint8_t)((*ptr)+1); ptr++;
1229 terminx 1758
    for (i=lzcols-1; i>=0; i--) { suffix[i] = (uint8_t)(prefix[i] = i); }
109 terminx 1759
    currstr = lzcols+2; numbits = startnumbits; numbitgoal = (lzcols<<1);
1760
    blocklen = *ptr++;
1425 terminx 1761
    Bmemcpy(filbuffer,ptr,blocklen); ptr += blocklen;
109 terminx 1762
    bitcnt = 0;
1763
    while (1)
1764
    {
1205 terminx 1765
        dat = (LSWAPIB(*(int32_t *)&filbuffer[bitcnt>>3])>>(bitcnt&7)) & (numbitgoal-1);
109 terminx 1766
        bitcnt += numbits;
1767
        if ((bitcnt>>3) > blocklen-3)
1768
        {
1205 terminx 1769
            *(int16_t *)filbuffer = *(int16_t *)&filbuffer[bitcnt>>3];
109 terminx 1770
            i = blocklen-(bitcnt>>3);
1205 terminx 1771
            blocklen = (int32_t)*ptr++;
1425 terminx 1772
            Bmemcpy(&filbuffer[i],ptr,blocklen); ptr += blocklen;
109 terminx 1773
            bitcnt &= 7; blocklen += i;
1774
        }
1775
        if (dat == lzcols)
1776
        {
1777
            currstr = lzcols+2; numbits = startnumbits; numbitgoal = (lzcols<<1);
1778
            continue;
1779
        }
1780
        if ((currstr == numbitgoal) && (numbits < 12))
584 terminx 1781
            { numbits++; numbitgoal <<= 1; }
5 Plagman 1782
 
109 terminx 1783
        prefix[currstr] = dat;
1229 terminx 1784
        for (i=0; dat>=lzcols; dat=prefix[dat]) tempstack[i++] = suffix[dat];
1205 terminx 1785
        tempstack[i] = (uint8_t)prefix[dat];
1786
        suffix[currstr-1] = suffix[currstr] = (uint8_t)dat;
5 Plagman 1787
 
1229 terminx 1788
        for (; i>=0; i--)
109 terminx 1789
        {
1205 terminx 1790
            if ((uint32_t)x < (uint32_t)daxres)
1791
                *(int32_t *)(yoff+(x<<2)) = palcol[(int32_t)tempstack[i]];
109 terminx 1792
            x++;
1793
            if (x == xend)
1794
            {
1795
                y += yinc;
1796
                if (y >= yspan)
331 terminx 1797
                    switch (yinc)
109 terminx 1798
                    {
1440 terminx 1799
                    case 8: if (!ilacefirst) { y = daglobyoffs+2; yinc = 4; break; }
109 terminx 1800
                        ilacefirst = 0; y = daglobyoffs+4; yinc = 8; break;
1440 terminx 1801
                    case 4: y = daglobyoffs+1; yinc = 2; break;
1802
                    case 2: case 1: return(0);
109 terminx 1803
                    }
1205 terminx 1804
                if ((uint32_t)y < (uint32_t)dayres)
584 terminx 1805
                    { yoff = y*dabytesperline+daframeplace; x = daglobxoffs; xend = xspan; }
109 terminx 1806
                else
584 terminx 1807
                    { x = daglobxoffs+0x80000000; xend = xspan+0x80000000; }
109 terminx 1808
            }
1809
        }
1810
        currstr++;
1811
    }
5 Plagman 1812
}
1813
 
1814
//===============================  GIF ends ==================================
1815
//==============================  CEL begins =================================
1816
 
109 terminx 1817
//   //old .CEL format:
1440 terminx 1818
//int16_t id = 0x9119, xdim, ydim, xoff, yoff, id = 0x0008;
1205 terminx 1819
//int32_t imagebytes, filler[4];
109 terminx 1820
//char pal6bit[256][3], image[ydim][xdim];
4634 terminx 1821
#ifdef KPCEL
1205 terminx 1822
static int32_t kcelrend(const char *buf, int32_t fleng,
4634 terminx 1823
                        intptr_t daframeplace, int32_t dabytesperline, int32_t daxres, int32_t dayres)
5 Plagman 1824
{
1205 terminx 1825
    int32_t i, x, y, x0, x1, y0, y1, xsiz, ysiz;
109 terminx 1826
    const char *cptr;
5 Plagman 1827
 
654 terminx 1828
    UNREFERENCED_PARAMETER(fleng);
1829
 
4634 terminx 1830
    kcoltype = 3; bitdepth = 8; paleng = 256; //For PNGOUT
5 Plagman 1831
 
1205 terminx 1832
    xsiz = (int32_t)SSWAPIB(*(uint16_t *)&buf[2]); if (xsiz <= 0) return(-1);
1833
    ysiz = (int32_t)SSWAPIB(*(uint16_t *)&buf[4]); if (ysiz <= 0) return(-1);
5 Plagman 1834
 
109 terminx 1835
    cptr = &buf[32];
1229 terminx 1836
    for (i=0; i<256; i++)
109 terminx 1837
    {
1205 terminx 1838
        palcol[i] = (((int32_t)cptr[0])<<18) +
1839
                    (((int32_t)cptr[1])<<10) +
1840
                    (((int32_t)cptr[2])<< 2) + LSWAPIB(0xff000000);
109 terminx 1841
        cptr += 3;
1842
    }
5 Plagman 1843
 
4634 terminx 1844
    x0 = 0; x1 = xsiz;
1845
    y0 = 0; y1 = ysiz;
1229 terminx 1846
    for (y=y0; y<y1; y++)
1847
        for (x=x0; x<x1; x++)
109 terminx 1848
        {
1205 terminx 1849
            if (((uint32_t)x < (uint32_t)daxres) && ((uint32_t)y < (uint32_t)dayres))
1850
                *(int32_t *)(y*dabytesperline+x*4+daframeplace) = palcol[cptr[0]];
109 terminx 1851
            cptr++;
1852
        }
1853
    return(0);
5 Plagman 1854
}
4634 terminx 1855
#endif
5 Plagman 1856
 
1857
//===============================  CEL ends ==================================
1858
//=============================  TARGA begins ================================
1859
 
1205 terminx 1860
static int32_t ktgarend(const char *header, int32_t fleng,
4634 terminx 1861
                        intptr_t daframeplace, int32_t dabytesperline, int32_t daxres, int32_t dayres)
5 Plagman 1862
{
1502 terminx 1863
    int32_t i = 0, x, y, pi, xi, yi, x0, x1, y0, y1, xsiz, ysiz, rlestat, colbyte, pixbyte;
737 qbix79 1864
    intptr_t p;
5 Plagman 1865
 
1502 terminx 1866
    const uint8_t *fptr, *cptr = NULL, *nptr;
1440 terminx 1867
 
109 terminx 1868
    //Ugly and unreliable identification for .TGA!
1481 terminx 1869
    if ((fleng < 19) || (header[1]&0xfe)) return(-1);
109 terminx 1870
    if ((header[2] >= 12) || (!((1<<header[2])&0xe0e))) return(-1);
1871
    if ((header[16]&7) || (header[16] == 0) || (header[16] > 32)) return(-1);
1872
    if (header[17]&0xc0) return(-1);
5 Plagman 1873
 
1440 terminx 1874
    fptr = (uint8_t *)&header[header[0]+18];
1205 terminx 1875
    xsiz = (int32_t)SSWAPIB(*(uint16_t *)&header[12])