Subversion Repositories eduke32

Rev

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