From fba7cf5bbb0c76fe0841350d80b389ac30973825 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Tue, 7 Feb 2006 16:37:40 +0000 Subject: [PATCH] All CRLF fixes --- modules/gui/skins2/unzip/crypt.h | 264 +-- modules/gui/skins2/unzip/ioapi.c | 354 ++-- modules/gui/skins2/unzip/ioapi.h | 150 +- modules/gui/skins2/unzip/unzip.c | 3208 +++++++++++++++--------------- modules/gui/skins2/unzip/unzip.h | 708 +++---- src/osd/osd.c | 1236 ++++++------ src/osd/osd_parser.c | 1414 ++++++------- 7 files changed, 3667 insertions(+), 3667 deletions(-) diff --git a/modules/gui/skins2/unzip/crypt.h b/modules/gui/skins2/unzip/crypt.h index f14a628b4c..622f4bc2ec 100644 --- a/modules/gui/skins2/unzip/crypt.h +++ b/modules/gui/skins2/unzip/crypt.h @@ -1,132 +1,132 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) -{ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const unsigned long* pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) + const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long* pkeys; + const unsigned long* pcrc_32_tab; + unsigned long crcForCrypting; +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/modules/gui/skins2/unzip/ioapi.c b/modules/gui/skins2/unzip/ioapi.c index 7f20c182f9..f1bee23e64 100644 --- a/modules/gui/skins2/unzip/ioapi.c +++ b/modules/gui/skins2/unzip/ioapi.c @@ -1,177 +1,177 @@ -/* ioapi.c -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#include -#include -#include - -#include "zlib.h" -#include "ioapi.h" - - - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -voidpf ZCALLBACK fopen_file_func OF(( - voidpf opaque, - const char* filename, - int mode)); - -uLong ZCALLBACK fread_file_func OF(( - voidpf opaque, - voidpf stream, - void* buf, - uLong size)); - -uLong ZCALLBACK fwrite_file_func OF(( - voidpf opaque, - voidpf stream, - const void* buf, - uLong size)); - -long ZCALLBACK ftell_file_func OF(( - voidpf opaque, - voidpf stream)); - -long ZCALLBACK fseek_file_func OF(( - voidpf opaque, - voidpf stream, - uLong offset, - int origin)); - -int ZCALLBACK fclose_file_func OF(( - voidpf opaque, - voidpf stream)); - -int ZCALLBACK ferror_file_func OF(( - voidpf opaque, - voidpf stream)); - - -voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) - voidpf opaque; - const char* filename; - int mode; -{ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; -} - - -uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - - -uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - const void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -long ZCALLBACK ftell_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - long ret; - ret = ftell((FILE *)stream); - return ret; -} - -long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) - voidpf opaque; - voidpf stream; - uLong offset; - int origin; -{ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - fseek((FILE *)stream, offset, fseek_origin); - return ret; -} - -int ZCALLBACK fclose_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = fclose((FILE *)stream); - return ret; -} - -int ZCALLBACK ferror_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = ferror((FILE *)stream); - return ret; -} - -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; -{ - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include +#include +#include + +#include "zlib.h" +#include "ioapi.h" + + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF(( + voidpf opaque, + const char* filename, + int mode)); + +uLong ZCALLBACK fread_file_func OF(( + voidpf opaque, + voidpf stream, + void* buf, + uLong size)); + +uLong ZCALLBACK fwrite_file_func OF(( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size)); + +long ZCALLBACK ftell_file_func OF(( + voidpf opaque, + voidpf stream)); + +long ZCALLBACK fseek_file_func OF(( + voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK fclose_file_func OF(( + voidpf opaque, + voidpf stream)); + +int ZCALLBACK ferror_file_func OF(( + voidpf opaque, + voidpf stream)); + + +voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + + +uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + + +uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/modules/gui/skins2/unzip/ioapi.h b/modules/gui/skins2/unzip/ioapi.h index e73a3b2bd8..7d457baab3 100644 --- a/modules/gui/skins2/unzip/ioapi.h +++ b/modules/gui/skins2/unzip/ioapi.h @@ -1,75 +1,75 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + + + +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/modules/gui/skins2/unzip/unzip.c b/modules/gui/skins2/unzip/unzip.c index 2a55e2bb5c..5e8763ad1d 100644 --- a/modules/gui/skins2/unzip/unzip.c +++ b/modules/gui/skins2/unzip/unzip.c @@ -1,1604 +1,1604 @@ -/* unzip.c -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Read unzip.h for more info -*/ - -/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of -compatibility with older software. The following is from the original crypt.c. Code -woven in by Terry Thorsen 1/2003. -*/ -/* - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* - crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - */ - -/* - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - */ - - -#include -#include -#include -#include "zlib.h" -#include "unzip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - - -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - - - -const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ - uLong offset_curfile;/* relative offset of local header 4 bytes */ -} unz_file_info_internal; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - - uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ - - uLong offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - uLong pos_local_extrafield; /* position in the local extra field in read*/ - - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - uLong rest_read_compressed; /* number of byte to be decompressed */ - uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; -} file_in_zip_read_info_s; - - -/* unz_s contain internal information about the zipfile -*/ -typedef struct -{ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info gi; /* public global information */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - uLong num_file; /* number of the current file in the zipfile*/ - uLong pos_in_central_dir; /* pos of the current file in the central dir*/ - uLong current_file_ok; /* flag about the usability of the current file*/ - uLong central_pos; /* position of the beginning of the central dir*/ - - uLong size_central_dir; /* size of the central directory */ - uLong offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info cur_file_info; /* public info about the current file in zip*/ - unz_file_info_internal cur_file_info_internal; /* private info about it*/ - file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif -} unz_s; - - -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unzlocal_getByte OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - int *pi; -{ - unsigned char c; - int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unzlocal_getShort OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i = 0; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unzlocal_getLong OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i = 0; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (fileName1,fileName2) - const char* fileName1; - const char* fileName2; -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) - const char* fileName1; - const char* fileName2; - int iCaseSensitivity; -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local uLong unzlocal_SearchCentralDir OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream)); - -local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) - const char *path; - zlib_filefunc_def* pzlib_filefunc_def; -{ - unz_s us; - unz_s *s; - uLong central_pos,uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - if (unz_copyright[0]!=' ') - return NULL; - - if (pzlib_filefunc_def==NULL) - fill_fopen_filefunc(&us.z_filefunc); - else - us.z_filefunc = *pzlib_filefunc_def; - - us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; - - central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; - - if (ZSEEK(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* zipfile comment length */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - ZCLOSE(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) - unzFile file; - unz_global_info *pglobal_info; -{ - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) - uLong ulDosDate; - tm_unz* ptm; -{ - uLong uDate; - uDate = (uLong)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -local int unzlocal_GetCurrentFileInfoInternal (file, - pfile_info, - pfile_info_internal, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - unz_file_info_internal *pfile_info_internal; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - unz_s* s; - unz_file_info file_info; - unz_file_info_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (ZSEEK(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - - if ((err==UNZ_OK) && (extraField!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek += file_info.size_file_extra - uSizeRead; - } - else - lSeek+=file_info.size_file_extra; - - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo (file, - pfile_info, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (file) - unzFile file; -{ - int err=UNZ_OK; - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (file) - unzFile file; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) - unzFile file; - const char *szFileName; - int iCaseSensitivity; -{ - unz_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info cur_file_infoSaved; - unz_file_info_internal cur_file_info_internalSaved; - uLong num_fileSaved; - uLong pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; // offset in file - uLong num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGoToFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, - poffset_local_extrafield, - psize_local_extrafield) - unz_s* s; - uInt* piSizeVar; - uLong *poffset_local_extrafield; - uInt *psize_local_extrafield; -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) - unzFile file; - int* method; - int* level; - int raw; - const char* password; -{ - int err=UNZ_OK; - uInt iSizeVar; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uLong offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip_read_info_s*) - ALLOC(sizeof(file_in_zip_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_DEFLATED) && - (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=1; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - s->pfile_in_zip_read = pfile_in_zip_read_info; - -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; -} - -extern int ZEXPORT unzOpenCurrentFile (file) - unzFile file; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword (file, password) - unzFile file; - const char* password; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) - unzFile file; - int* method; - int* level; - int raw; -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (file, buf, len) - unzFile file; - voidp buf; - unsigned len; -{ - int err=UNZ_OK; - uInt iRead = 0; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->read_buffer == NULL)) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else - { - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) - unzFile file; - voidp buf; - unsigned len; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uInt read_now; - uLong size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (file) - unzFile file; -{ - int err=UNZ_OK; - - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) - unzFile file; - char *szComment; - uLong uSizeBuf; -{ - unz_s* s; - uLong uReadThis ; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* Additions by RX '2004 */ -extern uLong ZEXPORT unzGetOffset (file) - unzFile file; -{ - unz_s* s; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; -} - -extern int ZEXPORT unzSetOffset (file, pos) - unzFile file; - uLong pos; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + Read unzip.h for more info +*/ + +/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of +compatibility with older software. The following is from the original crypt.c. Code +woven in by Terry Thorsen 1/2003. +*/ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i = 0; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) + const char *path; + zlib_filefunc_def* pzlib_filefunc_def; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; // offset in file + uLong num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + } + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) + unzFile file; + int* method; + int* level; + int raw; + const char* password; +{ + int err=UNZ_OK; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_DEFLATED) && + (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (file, password) + unzFile file; + const char* password; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) + unzFile file; + int* method; + int* level; + int raw; +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset (file) + unzFile file; +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset (file, pos) + unzFile file; + uLong pos; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/modules/gui/skins2/unzip/unzip.h b/modules/gui/skins2/unzip/unzip.h index c3206a0589..b247937c80 100644 --- a/modules/gui/skins2/unzip/unzip.h +++ b/modules/gui/skins2/unzip/unzip.h @@ -1,354 +1,354 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include "zlib.h" -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/src/osd/osd.c b/src/osd/osd.c index 4dacb004a7..189a546850 100644 --- a/src/osd/osd.c +++ b/src/osd/osd.c @@ -1,618 +1,618 @@ -/***************************************************************************** - * osd.c - The OSD Menu core code. - ***************************************************************************** - * Copyright (C) 2005 M2X - * $Id$ - * - * Authors: Jean-Paul Saman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include -#include - -#include -#include -#include - -#undef OSD_MENU_DEBUG - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ - -static void osd_UpdateState( osd_menu_state_t *, int, int, int, int, picture_t * ); -static inline osd_state_t *osd_VolumeStateChange( osd_state_t *, int ); -static int osd_VolumeStep( vlc_object_t *, int, int ); -static vlc_bool_t osd_isVisible( osd_menu_t *p_osd ); - -static vlc_bool_t osd_isVisible( osd_menu_t *p_osd ) -{ - vlc_value_t val; - - var_Get( p_osd, "osd-menu-visible", &val ); - return val.b_bool; -} - -/***************************************************************************** - * OSD menu Funtions - *****************************************************************************/ -osd_menu_t *__osd_MenuCreate( vlc_object_t *p_this, const char *psz_file ) -{ - osd_menu_t *p_osd = NULL; - vlc_value_t lockval; - int i_volume = 0; - int i_steps = 0; - - /* to be sure to avoid multiple creation */ - var_Create( p_this->p_libvlc, "osd_mutex", VLC_VAR_MUTEX ); - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - vlc_value_t val; - - msg_Dbg( p_this, "creating osd menu object" ); - if( ( p_osd = vlc_object_create( p_this, VLC_OBJECT_OSDMENU ) ) == NULL ) - { - msg_Err( p_this, "out of memory" ); - vlc_mutex_unlock( lockval.p_address ); - return NULL; - } - - /* Parse configuration file */ - if( osd_ConfigLoader( p_this, psz_file, &p_osd ) ) - goto error; - - /* Setup default button (first button) */ - p_osd->p_state->p_visible = p_osd->p_button; - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - p_osd->i_width = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch; - p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines; - - /* Update the volume state images to match the current volume */ - i_volume = config_GetInt( p_this, "volume" ); - i_steps = osd_VolumeStep( p_this, i_volume, p_osd->p_state->p_volume->i_ranges ); - p_osd->p_state->p_volume->p_current_state = osd_VolumeStateChange( p_osd->p_state->p_volume->p_states, i_steps ); - - /* Initialize OSD state */ - osd_UpdateState( p_osd->p_state, p_osd->i_x, p_osd->i_y, - p_osd->i_width, p_osd->i_height, NULL ); - - vlc_object_yield( p_osd ); - vlc_object_attach( p_osd, p_this->p_vlc ); - - /* Signal when an update of OSD menu is needed */ - var_Create( p_osd, "osd-menu-update", VLC_VAR_BOOL ); - var_Create( p_osd, "osd-menu-visible", VLC_VAR_BOOL ); - - val.b_bool = VLC_FALSE; - var_Set( p_osd, "osd-menu-update", val ); - var_Set( p_osd, "osd-menu-visible", val ); - } - vlc_mutex_unlock( lockval.p_address ); - return p_osd; - -error: - msg_Err( p_this, "creating osd menu object failed" ); - vlc_mutex_unlock( lockval.p_address ); - vlc_object_destroy( p_osd ); - return NULL; -} - -void __osd_MenuDelete( vlc_object_t *p_this, osd_menu_t *p_osd ) -{ - vlc_value_t lockval; - - if( !p_osd || !p_this ) return; - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - vlc_object_release( p_osd ); - if( p_osd->i_refcount > 0 ) - { - vlc_mutex_unlock( lockval.p_address ); - return; - } - - var_Destroy( p_osd, "osd-menu-visible" ); - var_Destroy( p_osd, "osd-menu-update" ); - - osd_ConfigUnload( p_this, &p_osd ); - vlc_object_detach( p_osd ); - vlc_object_destroy( p_osd ); - p_osd = NULL; - - vlc_mutex_unlock( lockval.p_address ); -} - -osd_state_t *__osd_StateChange( osd_state_t *p_states, const int i_state ) -{ - osd_state_t *p_current = p_states; - osd_state_t *p_temp = NULL; - int i = 0; - - for( i=0; p_current != NULL; i++ ) - { - if( p_current->i_state == i_state ) - return p_current; - p_temp = p_current->p_next; - p_current = p_temp; - } - return p_states; -} - -/* The volume can be modified in another interface while the OSD Menu - * has not been instantiated yet. This routines updates the "volume OSD menu item" - * to reflect the current state of the GUI. - */ -static inline osd_state_t *osd_VolumeStateChange( osd_state_t *p_current, int i_steps ) -{ - osd_state_t *p_temp = NULL; - int i; - - if( i_steps < 0 ) i_steps = 0; - - for( i=0; (i < i_steps) && (p_current != NULL); i++ ) - { - p_temp = p_current->p_next; - if( !p_temp ) return p_current; - p_current = p_temp; - } - return (!p_temp) ? p_current : p_temp; -} - -/* Update the state of the OSD Menu */ -static void osd_UpdateState( osd_menu_state_t *p_state, int i_x, int i_y, - int i_width, int i_height, picture_t *p_pic ) -{ - p_state->i_x = i_x; - p_state->i_y = i_y; - p_state->i_width = i_width; - p_state->i_height = i_height; - p_state->p_pic = p_pic; -} - -void __osd_MenuShow( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuNext failed" ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "menu on" ); -#endif - p_button = p_osd->p_state->p_visible; - if( p_button ) - { - if( !p_button->b_range ) - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); - p_osd->p_state->p_visible = p_osd->p_button; - - if( !p_osd->p_state->p_visible->b_range ) - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - - osd_UpdateState( p_osd->p_state, - p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_osd->p_state->p_visible->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - } - osd_SetMenuVisible( p_osd, VLC_TRUE ); - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuHide( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - vlc_value_t lockval; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuNext failed" ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "menu off" ); -#endif - osd_UpdateState( p_osd->p_state, - p_osd->p_state->i_x, p_osd->p_state->i_y, - 0, 0, NULL ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuActivate( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuNext failed" ); - return; - } - - if( osd_isVisible( p_osd ) == VLC_FALSE ) - { - vlc_object_release( (vlc_object_t*) p_osd ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "select" ); -#endif - p_button = p_osd->p_state->p_visible; - /* - * Is there a menu item above or below? If so, then select it. - */ - if( p_button && p_button->p_up) - { - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); - __osd_MenuUp( p_this ); /* "menu select" means go to menu item above. */ - return; - } - if( p_button && p_button->p_down) - { - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); - __osd_MenuDown( p_this ); /* "menu select" means go to menu item below. */ - return; - } - - if( p_button && !p_button->b_range ) - { - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_PRESSED ); - osd_UpdateState( p_osd->p_state, - p_button->i_x, p_button->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_button->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - osd_SetMenuVisible( p_osd, VLC_TRUE ); - osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt( p_osd, p_button->psz_action ) ); -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "select (%d, %s)", config_GetInt( p_osd, p_button->psz_action ), p_button->psz_action ); -#endif - } - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuNext( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuNext failed" ); - return; - } - - if( osd_isVisible( p_osd ) == VLC_FALSE ) - { - vlc_object_release( (vlc_object_t*) p_osd ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - p_button = p_osd->p_state->p_visible; - if( p_button ) - { - if( !p_button->b_range ) - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); - if( p_button->p_next ) - p_osd->p_state->p_visible = p_button->p_next; - else - p_osd->p_state->p_visible = p_osd->p_button; - - if( !p_osd->p_state->p_visible->b_range ) - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - - osd_UpdateState( p_osd->p_state, - p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_osd->p_state->p_visible->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - } -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "direction right [button %s]", p_osd->p_state->p_visible->psz_action ); -#endif - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuPrev( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuPrev failed" ); - return; - } - - if( osd_isVisible( p_osd ) == VLC_FALSE ) - { - vlc_object_release( (vlc_object_t*) p_osd ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - p_button = p_osd->p_state->p_visible; - if( p_button ) - { - if( !p_button->b_range ) - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); - if( p_button->p_prev ) - p_osd->p_state->p_visible = p_button->p_prev; - else - p_osd->p_state->p_visible = p_osd->p_last_button; - - if( !p_osd->p_state->p_visible->b_range ) - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - - osd_UpdateState( p_osd->p_state, - p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_osd->p_state->p_visible->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - } -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "direction left [button %s]", p_osd->p_state->p_visible->psz_action ); -#endif - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuUp( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; -#if defined(OSD_MENU_DEBUG) - vlc_value_t val; -#endif - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuDown failed" ); - return; - } - - if( osd_isVisible( p_osd ) == VLC_FALSE ) - { - vlc_object_release( (vlc_object_t*) p_osd ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - p_button = p_osd->p_state->p_visible; - if( p_button ) - { - if( !p_button->b_range ) - { - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); - if( p_button->p_up ) - p_osd->p_state->p_visible = p_button->p_up; - } - - if( p_button->b_range && p_osd->p_state->p_visible->b_range ) - { - osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state; - if( p_temp && p_temp->p_next ) - p_osd->p_state->p_visible->p_current_state = p_temp->p_next; - } - else if( !p_osd->p_state->p_visible->b_range ) - { - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - } - - osd_UpdateState( p_osd->p_state, - p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_osd->p_state->p_visible->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - /* If this is a range style action with associated images of only one state, - * then perform "menu select" on every menu navigation - */ - if( p_button->b_range ) - { - osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action) ); -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action ); -#endif - } - } -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "direction up [button %s]", p_osd->p_state->p_visible->psz_action ); -#endif - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -void __osd_MenuDown( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; -#if defined(OSD_MENU_DEBUG) - vlc_value_t val; -#endif - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "osd_MenuDown failed" ); - return; - } - - if( osd_isVisible( p_osd ) == VLC_FALSE ) - { - vlc_object_release( (vlc_object_t*) p_osd ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - p_button = p_osd->p_state->p_visible; - if( p_button ) - { - if( !p_button->b_range ) - { - p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); - if( p_button->p_down ) - p_osd->p_state->p_visible = p_button->p_down; - } - - if( p_button->b_range && p_osd->p_state->p_visible->b_range ) - { - osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state; - if( p_temp && p_temp->p_prev ) - p_osd->p_state->p_visible->p_current_state = p_temp->p_prev; - } - else if( !p_osd->p_state->p_visible->b_range ) - { - p_osd->p_state->p_visible->p_current_state = - osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); - } - - osd_UpdateState( p_osd->p_state, - p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_osd->p_state->p_visible->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - /* If this is a range style action with associated images of only one state, - * then perform "menu select" on every menu navigation - */ - if( p_button->b_range ) - { - osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action_down) ); -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action_down ); -#endif - } - } -#if defined(OSD_MENU_DEBUG) - msg_Dbg( p_osd, "direction down [button %s]", p_osd->p_state->p_visible->psz_action ); -#endif - - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} - -static int osd_VolumeStep( vlc_object_t *p_this, int i_volume, int i_steps ) -{ - int i_volume_step = 0; - - i_volume_step = config_GetInt( p_this->p_vlc, "volume-step" ); - return (i_volume/i_volume_step); -} - -/** - * Display current audio volume bitmap - * - * The OSD Menu audio volume bar is updated to reflect the new audio volume. Call this function - * when the audio volume is updated outside the OSD menu command "menu up", "menu down" or "menu select". - */ -void __osd_Volume( vlc_object_t *p_this ) -{ - osd_menu_t *p_osd = NULL; - osd_button_t *p_button = NULL; - vlc_value_t lockval; - int i_volume = 0; - int i_steps = 0; - - if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) - { - msg_Err( p_this, "OSD menu volume update failed" ); - return; - } - - var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); - vlc_mutex_lock( lockval.p_address ); - - p_button = p_osd->p_state->p_volume; - if( p_osd->p_state->p_volume ) - p_osd->p_state->p_visible = p_osd->p_state->p_volume; - if( p_button && p_button->b_range ) - { - /* Update the volume state images to match the current volume */ - i_volume = config_GetInt( p_this, "volume" ); - i_steps = osd_VolumeStep( p_this, i_volume, p_button->i_ranges ); - p_button->p_current_state = osd_VolumeStateChange( p_button->p_states, i_steps ); - - osd_UpdateState( p_osd->p_state, - p_button->i_x, p_button->i_y, - p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, - p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, - p_button->p_current_state->p_pic ); - osd_SetMenuUpdate( p_osd, VLC_TRUE ); - osd_SetMenuVisible( p_osd, VLC_TRUE ); - } - vlc_object_release( (vlc_object_t*) p_osd ); - vlc_mutex_unlock( lockval.p_address ); -} +/***************************************************************************** + * osd.c - The OSD Menu core code. + ***************************************************************************** + * Copyright (C) 2005 M2X + * $Id$ + * + * Authors: Jean-Paul Saman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include +#include + +#include +#include +#include + +#undef OSD_MENU_DEBUG + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + +static void osd_UpdateState( osd_menu_state_t *, int, int, int, int, picture_t * ); +static inline osd_state_t *osd_VolumeStateChange( osd_state_t *, int ); +static int osd_VolumeStep( vlc_object_t *, int, int ); +static vlc_bool_t osd_isVisible( osd_menu_t *p_osd ); + +static vlc_bool_t osd_isVisible( osd_menu_t *p_osd ) +{ + vlc_value_t val; + + var_Get( p_osd, "osd-menu-visible", &val ); + return val.b_bool; +} + +/***************************************************************************** + * OSD menu Funtions + *****************************************************************************/ +osd_menu_t *__osd_MenuCreate( vlc_object_t *p_this, const char *psz_file ) +{ + osd_menu_t *p_osd = NULL; + vlc_value_t lockval; + int i_volume = 0; + int i_steps = 0; + + /* to be sure to avoid multiple creation */ + var_Create( p_this->p_libvlc, "osd_mutex", VLC_VAR_MUTEX ); + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + vlc_value_t val; + + msg_Dbg( p_this, "creating osd menu object" ); + if( ( p_osd = vlc_object_create( p_this, VLC_OBJECT_OSDMENU ) ) == NULL ) + { + msg_Err( p_this, "out of memory" ); + vlc_mutex_unlock( lockval.p_address ); + return NULL; + } + + /* Parse configuration file */ + if( osd_ConfigLoader( p_this, psz_file, &p_osd ) ) + goto error; + + /* Setup default button (first button) */ + p_osd->p_state->p_visible = p_osd->p_button; + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + p_osd->i_width = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch; + p_osd->i_height = p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines; + + /* Update the volume state images to match the current volume */ + i_volume = config_GetInt( p_this, "volume" ); + i_steps = osd_VolumeStep( p_this, i_volume, p_osd->p_state->p_volume->i_ranges ); + p_osd->p_state->p_volume->p_current_state = osd_VolumeStateChange( p_osd->p_state->p_volume->p_states, i_steps ); + + /* Initialize OSD state */ + osd_UpdateState( p_osd->p_state, p_osd->i_x, p_osd->i_y, + p_osd->i_width, p_osd->i_height, NULL ); + + vlc_object_yield( p_osd ); + vlc_object_attach( p_osd, p_this->p_vlc ); + + /* Signal when an update of OSD menu is needed */ + var_Create( p_osd, "osd-menu-update", VLC_VAR_BOOL ); + var_Create( p_osd, "osd-menu-visible", VLC_VAR_BOOL ); + + val.b_bool = VLC_FALSE; + var_Set( p_osd, "osd-menu-update", val ); + var_Set( p_osd, "osd-menu-visible", val ); + } + vlc_mutex_unlock( lockval.p_address ); + return p_osd; + +error: + msg_Err( p_this, "creating osd menu object failed" ); + vlc_mutex_unlock( lockval.p_address ); + vlc_object_destroy( p_osd ); + return NULL; +} + +void __osd_MenuDelete( vlc_object_t *p_this, osd_menu_t *p_osd ) +{ + vlc_value_t lockval; + + if( !p_osd || !p_this ) return; + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + vlc_object_release( p_osd ); + if( p_osd->i_refcount > 0 ) + { + vlc_mutex_unlock( lockval.p_address ); + return; + } + + var_Destroy( p_osd, "osd-menu-visible" ); + var_Destroy( p_osd, "osd-menu-update" ); + + osd_ConfigUnload( p_this, &p_osd ); + vlc_object_detach( p_osd ); + vlc_object_destroy( p_osd ); + p_osd = NULL; + + vlc_mutex_unlock( lockval.p_address ); +} + +osd_state_t *__osd_StateChange( osd_state_t *p_states, const int i_state ) +{ + osd_state_t *p_current = p_states; + osd_state_t *p_temp = NULL; + int i = 0; + + for( i=0; p_current != NULL; i++ ) + { + if( p_current->i_state == i_state ) + return p_current; + p_temp = p_current->p_next; + p_current = p_temp; + } + return p_states; +} + +/* The volume can be modified in another interface while the OSD Menu + * has not been instantiated yet. This routines updates the "volume OSD menu item" + * to reflect the current state of the GUI. + */ +static inline osd_state_t *osd_VolumeStateChange( osd_state_t *p_current, int i_steps ) +{ + osd_state_t *p_temp = NULL; + int i; + + if( i_steps < 0 ) i_steps = 0; + + for( i=0; (i < i_steps) && (p_current != NULL); i++ ) + { + p_temp = p_current->p_next; + if( !p_temp ) return p_current; + p_current = p_temp; + } + return (!p_temp) ? p_current : p_temp; +} + +/* Update the state of the OSD Menu */ +static void osd_UpdateState( osd_menu_state_t *p_state, int i_x, int i_y, + int i_width, int i_height, picture_t *p_pic ) +{ + p_state->i_x = i_x; + p_state->i_y = i_y; + p_state->i_width = i_width; + p_state->i_height = i_height; + p_state->p_pic = p_pic; +} + +void __osd_MenuShow( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuNext failed" ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "menu on" ); +#endif + p_button = p_osd->p_state->p_visible; + if( p_button ) + { + if( !p_button->b_range ) + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); + p_osd->p_state->p_visible = p_osd->p_button; + + if( !p_osd->p_state->p_visible->b_range ) + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + + osd_UpdateState( p_osd->p_state, + p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_osd->p_state->p_visible->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + } + osd_SetMenuVisible( p_osd, VLC_TRUE ); + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuHide( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + vlc_value_t lockval; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuNext failed" ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "menu off" ); +#endif + osd_UpdateState( p_osd->p_state, + p_osd->p_state->i_x, p_osd->p_state->i_y, + 0, 0, NULL ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuActivate( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuNext failed" ); + return; + } + + if( osd_isVisible( p_osd ) == VLC_FALSE ) + { + vlc_object_release( (vlc_object_t*) p_osd ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "select" ); +#endif + p_button = p_osd->p_state->p_visible; + /* + * Is there a menu item above or below? If so, then select it. + */ + if( p_button && p_button->p_up) + { + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); + __osd_MenuUp( p_this ); /* "menu select" means go to menu item above. */ + return; + } + if( p_button && p_button->p_down) + { + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); + __osd_MenuDown( p_this ); /* "menu select" means go to menu item below. */ + return; + } + + if( p_button && !p_button->b_range ) + { + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_PRESSED ); + osd_UpdateState( p_osd->p_state, + p_button->i_x, p_button->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_button->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + osd_SetMenuVisible( p_osd, VLC_TRUE ); + osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt( p_osd, p_button->psz_action ) ); +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "select (%d, %s)", config_GetInt( p_osd, p_button->psz_action ), p_button->psz_action ); +#endif + } + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuNext( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuNext failed" ); + return; + } + + if( osd_isVisible( p_osd ) == VLC_FALSE ) + { + vlc_object_release( (vlc_object_t*) p_osd ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + p_button = p_osd->p_state->p_visible; + if( p_button ) + { + if( !p_button->b_range ) + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); + if( p_button->p_next ) + p_osd->p_state->p_visible = p_button->p_next; + else + p_osd->p_state->p_visible = p_osd->p_button; + + if( !p_osd->p_state->p_visible->b_range ) + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + + osd_UpdateState( p_osd->p_state, + p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_osd->p_state->p_visible->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + } +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "direction right [button %s]", p_osd->p_state->p_visible->psz_action ); +#endif + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuPrev( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuPrev failed" ); + return; + } + + if( osd_isVisible( p_osd ) == VLC_FALSE ) + { + vlc_object_release( (vlc_object_t*) p_osd ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + p_button = p_osd->p_state->p_visible; + if( p_button ) + { + if( !p_button->b_range ) + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_UNSELECT ); + if( p_button->p_prev ) + p_osd->p_state->p_visible = p_button->p_prev; + else + p_osd->p_state->p_visible = p_osd->p_last_button; + + if( !p_osd->p_state->p_visible->b_range ) + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + + osd_UpdateState( p_osd->p_state, + p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_osd->p_state->p_visible->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + } +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "direction left [button %s]", p_osd->p_state->p_visible->psz_action ); +#endif + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuUp( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; +#if defined(OSD_MENU_DEBUG) + vlc_value_t val; +#endif + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuDown failed" ); + return; + } + + if( osd_isVisible( p_osd ) == VLC_FALSE ) + { + vlc_object_release( (vlc_object_t*) p_osd ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + p_button = p_osd->p_state->p_visible; + if( p_button ) + { + if( !p_button->b_range ) + { + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); + if( p_button->p_up ) + p_osd->p_state->p_visible = p_button->p_up; + } + + if( p_button->b_range && p_osd->p_state->p_visible->b_range ) + { + osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state; + if( p_temp && p_temp->p_next ) + p_osd->p_state->p_visible->p_current_state = p_temp->p_next; + } + else if( !p_osd->p_state->p_visible->b_range ) + { + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + } + + osd_UpdateState( p_osd->p_state, + p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_osd->p_state->p_visible->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + /* If this is a range style action with associated images of only one state, + * then perform "menu select" on every menu navigation + */ + if( p_button->b_range ) + { + osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action) ); +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action ); +#endif + } + } +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "direction up [button %s]", p_osd->p_state->p_visible->psz_action ); +#endif + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +void __osd_MenuDown( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; +#if defined(OSD_MENU_DEBUG) + vlc_value_t val; +#endif + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "osd_MenuDown failed" ); + return; + } + + if( osd_isVisible( p_osd ) == VLC_FALSE ) + { + vlc_object_release( (vlc_object_t*) p_osd ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + p_button = p_osd->p_state->p_visible; + if( p_button ) + { + if( !p_button->b_range ) + { + p_button->p_current_state = osd_StateChange( p_button->p_states, OSD_BUTTON_SELECT ); + if( p_button->p_down ) + p_osd->p_state->p_visible = p_button->p_down; + } + + if( p_button->b_range && p_osd->p_state->p_visible->b_range ) + { + osd_state_t *p_temp = p_osd->p_state->p_visible->p_current_state; + if( p_temp && p_temp->p_prev ) + p_osd->p_state->p_visible->p_current_state = p_temp->p_prev; + } + else if( !p_osd->p_state->p_visible->b_range ) + { + p_osd->p_state->p_visible->p_current_state = + osd_StateChange( p_osd->p_state->p_visible->p_states, OSD_BUTTON_SELECT ); + } + + osd_UpdateState( p_osd->p_state, + p_osd->p_state->p_visible->i_x, p_osd->p_state->p_visible->i_y, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_osd->p_state->p_visible->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_osd->p_state->p_visible->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + /* If this is a range style action with associated images of only one state, + * then perform "menu select" on every menu navigation + */ + if( p_button->b_range ) + { + osd_SetKeyPressed( VLC_OBJECT(p_osd->p_vlc), config_GetInt(p_osd, p_button->psz_action_down) ); +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "select (%d, %s)", val.i_int, p_button->psz_action_down ); +#endif + } + } +#if defined(OSD_MENU_DEBUG) + msg_Dbg( p_osd, "direction down [button %s]", p_osd->p_state->p_visible->psz_action ); +#endif + + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} + +static int osd_VolumeStep( vlc_object_t *p_this, int i_volume, int i_steps ) +{ + int i_volume_step = 0; + + i_volume_step = config_GetInt( p_this->p_vlc, "volume-step" ); + return (i_volume/i_volume_step); +} + +/** + * Display current audio volume bitmap + * + * The OSD Menu audio volume bar is updated to reflect the new audio volume. Call this function + * when the audio volume is updated outside the OSD menu command "menu up", "menu down" or "menu select". + */ +void __osd_Volume( vlc_object_t *p_this ) +{ + osd_menu_t *p_osd = NULL; + osd_button_t *p_button = NULL; + vlc_value_t lockval; + int i_volume = 0; + int i_steps = 0; + + if( ( p_osd = vlc_object_find( p_this, VLC_OBJECT_OSDMENU, FIND_ANYWHERE ) ) == NULL ) + { + msg_Err( p_this, "OSD menu volume update failed" ); + return; + } + + var_Get( p_this->p_libvlc, "osd_mutex", &lockval ); + vlc_mutex_lock( lockval.p_address ); + + p_button = p_osd->p_state->p_volume; + if( p_osd->p_state->p_volume ) + p_osd->p_state->p_visible = p_osd->p_state->p_volume; + if( p_button && p_button->b_range ) + { + /* Update the volume state images to match the current volume */ + i_volume = config_GetInt( p_this, "volume" ); + i_steps = osd_VolumeStep( p_this, i_volume, p_button->i_ranges ); + p_button->p_current_state = osd_VolumeStateChange( p_button->p_states, i_steps ); + + osd_UpdateState( p_osd->p_state, + p_button->i_x, p_button->i_y, + p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_pitch, + p_button->p_current_state->p_pic->p[Y_PLANE].i_visible_lines, + p_button->p_current_state->p_pic ); + osd_SetMenuUpdate( p_osd, VLC_TRUE ); + osd_SetMenuVisible( p_osd, VLC_TRUE ); + } + vlc_object_release( (vlc_object_t*) p_osd ); + vlc_mutex_unlock( lockval.p_address ); +} diff --git a/src/osd/osd_parser.c b/src/osd/osd_parser.c index bfebb3f2d9..09efef8718 100644 --- a/src/osd/osd_parser.c +++ b/src/osd/osd_parser.c @@ -1,707 +1,707 @@ -/***************************************************************************** - * osd_parser.c - The OSD Menu parser core code. - ***************************************************************************** - * Copyright (C) 2005 M2X - * $Id$ - * - * Authors: Jean-Paul Saman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. - *****************************************************************************/ - -/***************************************************************************** - * Preamble - *****************************************************************************/ -#include -#include - -#include -#include -#include - -#include -#include -#include - - -#undef OSD_MENU_DEBUG - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static const char *ppsz_button_states[] = { "unselect", "select", "pressed" }; - -/* OSD Menu structure support routines */ -static osd_menu_t *osd_MenuNew( osd_menu_t *, const char *, int, int ); -static osd_button_t *osd_ButtonNew( const char *, int, int ); -static osd_state_t *osd_StateNew( vlc_object_t *, const char *, const char * ); - -static void osd_MenuFree ( vlc_object_t *, osd_menu_t * ); -static void osd_ButtonFree( vlc_object_t *, osd_button_t * ); -static void osd_StatesFree( vlc_object_t *, osd_state_t * ); - -static picture_t *osd_LoadImage( vlc_object_t *, const char *); - -/***************************************************************************** - * osd_LoadImage: loads the logo image into memory - *****************************************************************************/ -static picture_t *osd_LoadImage( vlc_object_t *p_this, const char *psz_filename ) -{ - picture_t *p_pic = NULL; - image_handler_t *p_image; - video_format_t fmt_in = {0}, fmt_out = {0}; - - fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); - p_image = image_HandlerCreate( p_this ); - if( p_image ) - { - p_pic = image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out ); - image_HandlerDelete( p_image ); -#if 0 - p_pic = osd_YuvaYuvp( p_this, p_pic ); -#endif - } - else msg_Err( p_this, "unable to handle this chroma" ); - - return p_pic; -} - -/***************************************************************************** - * Create a new Menu structure - *****************************************************************************/ -static osd_menu_t *osd_MenuNew( osd_menu_t *p_menu, const char *psz_path, int i_x, int i_y ) -{ - if( !p_menu ) return NULL; - - p_menu->p_state = (osd_menu_state_t *) malloc( sizeof( osd_menu_state_t ) ); - if( !p_menu->p_state ) - msg_Err( p_menu, "memory allocation for OSD Menu state failed." ); - - if( psz_path != NULL ) - p_menu->psz_path = strdup( psz_path ); - else - p_menu->psz_path = NULL; - p_menu->i_x = i_x; - p_menu->i_y = i_y; - - return p_menu; -} - -/***************************************************************************** - * Free the menu - *****************************************************************************/ -static void osd_MenuFree( vlc_object_t *p_this, osd_menu_t *p_menu ) -{ - msg_Dbg( p_this, "freeing menu" ); - osd_ButtonFree( p_this, p_menu->p_button ); - p_menu->p_button = NULL; - p_menu->p_last_button = NULL; - if( p_menu->psz_path ) free( p_menu->psz_path ); - p_menu->psz_path = NULL; - if( p_menu->p_state ) free( p_menu->p_state ); - p_menu->p_state = NULL; -} - -/***************************************************************************** - * Create a new button - *****************************************************************************/ -static osd_button_t *osd_ButtonNew( const char *psz_action, int i_x, int i_y ) -{ - osd_button_t *p_button = NULL; - p_button = (osd_button_t*) malloc( sizeof(osd_button_t) ); - if( !p_button ) - return NULL; - - memset( p_button, 0, sizeof(osd_button_t) ); - p_button->psz_action = strdup(psz_action); - p_button->psz_action_down = NULL; - p_button->p_feedback = NULL; - p_button->i_x = i_x; - p_button->i_y = i_y; - - return p_button; -} - -/***************************************************************************** - * Free a button - *****************************************************************************/ -static void osd_ButtonFree( vlc_object_t *p_this, osd_button_t *p_button ) -{ - osd_button_t *p_current = p_button; - osd_button_t *p_next = NULL; - osd_button_t *p_prev = NULL; - - /* First walk to the end. */ - while( p_current->p_next ) - { - p_next = p_current->p_next; - p_current = p_next; - } - /* Then free end first and walk to the start. */ - while( p_current->p_prev ) - { - msg_Dbg( p_this, "+ freeing button %s [%p]", p_current->psz_action, p_current ); - p_prev = p_current->p_prev; - p_current = p_prev; - if( p_current->p_next ) - { - if( p_current->p_next->psz_name ) - free( p_current->p_next->psz_name ); - if( p_current->p_next->psz_action ) - free( p_current->p_next->psz_action ); - if( p_current->p_next->psz_action_down ) - free( p_current->p_next->psz_action_down ); - if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) - free( p_current->p_feedback->p_data_orig ); - if( p_current->p_feedback ) - free( p_current->p_feedback ); - - p_current->p_next->psz_action_down = NULL; - p_current->p_next->psz_action = NULL; - p_current->p_next->psz_name = NULL; - p_current->p_feedback = NULL; - - /* Free all states first */ - if( p_current->p_next->p_states ) - osd_StatesFree( p_this, p_current->p_next->p_states ); - p_current->p_next->p_states = NULL; - if( p_current->p_next) free( p_current->p_next ); - p_current->p_next = NULL; - } - - if( p_current->p_up ) - { - if( p_current->p_up->psz_name ) - free( p_current->p_up->psz_name ); - if( p_current->p_up->psz_action ) - free( p_current->p_up->psz_action ); - if( p_current->p_up->psz_action_down ) - free( p_current->p_up->psz_action_down ); - if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) - free( p_current->p_feedback->p_data_orig ); - if( p_current->p_feedback ) - free( p_current->p_feedback ); - - p_current->p_up->psz_action_down = NULL; - p_current->p_up->psz_action = NULL; - p_current->p_up->psz_name = NULL; - p_current->p_feedback = NULL; - - /* Free all states first */ - if( p_current->p_up->p_states ) - osd_StatesFree( p_this, p_current->p_up->p_states ); - p_current->p_up->p_states = NULL; - if( p_current->p_up ) free( p_current->p_up ); - p_current->p_up = NULL; - } - } - /* Free the last one. */ - if( p_button ) - { - msg_Dbg( p_this, "+ freeing button %s [%p]", p_button->psz_action, p_button ); - if( p_button->psz_name ) free( p_button->psz_name ); - if( p_button->psz_action ) free( p_button->psz_action ); - if( p_button->psz_action_down ) free( p_button->psz_action_down ); - if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) - free( p_current->p_feedback->p_data_orig ); - if( p_current->p_feedback ) - free( p_current->p_feedback ); - - p_button->psz_name = NULL; - p_button->psz_action = NULL; - p_button->psz_action_down = NULL; - p_current->p_feedback = NULL; - - if( p_button->p_states ) - osd_StatesFree( p_this, p_button->p_states ); - p_button->p_states = NULL; - free( p_button ); - p_button = NULL; - } -} - -/***************************************************************************** - * Create a new state image - *****************************************************************************/ -static osd_state_t *osd_StateNew( vlc_object_t *p_this, const char *psz_file, const char *psz_state ) -{ - osd_state_t *p_state = NULL; - p_state = (osd_state_t*) malloc( sizeof(osd_state_t) ); - if( !p_state ) - return NULL; - - memset( p_state, 0, sizeof(osd_state_t) ); - p_state->p_pic = osd_LoadImage( p_this, psz_file ); - - if( psz_state ) - { - p_state->psz_state = strdup( psz_state ); - if( strncmp( ppsz_button_states[0], psz_state, strlen(ppsz_button_states[0]) ) == 0 ) - p_state->i_state = OSD_BUTTON_UNSELECT; - else if( strncmp( ppsz_button_states[1], psz_state, strlen(ppsz_button_states[1]) ) == 0 ) - p_state->i_state = OSD_BUTTON_SELECT; - else if( strncmp( ppsz_button_states[2], psz_state, strlen(ppsz_button_states[2]) ) == 0 ) - p_state->i_state = OSD_BUTTON_PRESSED; - } - return p_state; -} - -/***************************************************************************** - * Free state images - *****************************************************************************/ -static void osd_StatesFree( vlc_object_t *p_this, osd_state_t *p_states ) -{ - osd_state_t *p_state = p_states; - osd_state_t *p_next = NULL; - osd_state_t *p_prev = NULL; - - while( p_state->p_next ) - { - p_next = p_state->p_next; - p_state = p_next; - } - /* Then free end first and walk to the start. */ - while( p_state->p_prev ) - { - msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_state ); - p_prev = p_state->p_prev; - p_state = p_prev; - if( p_state->p_next ) - { - if( p_state->p_next->p_pic && p_state->p_next->p_pic->p_data_orig ) - free( p_state->p_next->p_pic->p_data_orig ); - if( p_state->p_next->p_pic ) free( p_state->p_next->p_pic ); - p_state->p_next->p_pic = NULL; - if( p_state->p_next->psz_state ) free( p_state->p_next->psz_state ); - p_state->p_next->psz_state = NULL; - free( p_state->p_next ); - p_state->p_next = NULL; - } - } - /* Free the last one. */ - if( p_states ) - { - msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_states ); - if( p_states->p_pic && p_states->p_pic->p_data_orig ) - free( p_states->p_pic->p_data_orig ); - if( p_states->p_pic ) free( p_states->p_pic ); - p_states->p_pic = NULL; - if( p_state->psz_state ) free( p_state->psz_state ); - p_state->psz_state = NULL; - free( p_states ); - p_states = NULL; - } -} - -/***************************************************************************** - * osd_ConfigLoader: Load and parse osd text configurationfile - *****************************************************************************/ -int osd_ConfigLoader( vlc_object_t *p_this, const char *psz_file, - osd_menu_t **p_menu ) -{ - osd_button_t *p_current = NULL; /* button currently processed */ - osd_button_t *p_prev = NULL; /* previous processed button */ - -#define MAX_FILE_PATH 256 - FILE *fd = NULL; - int result = 0; - - msg_Dbg( p_this, "opening osd definition file %s", psz_file ); - fd = fopen( psz_file, "r" ); - if( !fd ) - { - msg_Err( p_this, "failed opening osd definition file %s", psz_file ); - return VLC_EGENERIC; - } - - /* Read first line */ - if( !feof( fd ) ) - { - char action[25] = ""; - char path[MAX_FILE_PATH] = ""; - char *psz_path = NULL; - size_t i_len = 0; - - /* override images path ? */ - psz_path = config_GetPsz( p_this, "osdmenu-file-path" ); - if( psz_path == NULL ) - { - result = fscanf(fd, "%24s %255s", &action[0], &path[0] ); - } - else - { - /* psz_path is not null and therefor &path[0] cannot be NULL - * it might be null terminated. - */ - strncpy( &path[0], psz_path, MAX_FILE_PATH ); - free( psz_path ); - psz_path = NULL; - } - /* NULL terminate before asking the length of path[] */ - path[MAX_FILE_PATH-1] = '\0'; - i_len = strlen(&path[0]); - if( i_len == MAX_FILE_PATH ) - i_len--; /* truncate to prevent buffer overflow */ -#if defined(WIN32) || defined(UNDER_CE) - if( (i_len > 0) && path[i_len] != '\\' ) - path[i_len] = '\\'; -#else - if( (i_len > 0) && path[i_len] != '/' ) - path[i_len] = '/'; -#endif - path[i_len+1] = '\0'; - if( result == 0 || result == EOF ) - goto error; - msg_Dbg( p_this, "%s=%s", &action[0], &path[0] ); - - if( i_len == 0 ) - *p_menu = osd_MenuNew( *p_menu, NULL, 0, 0 ); - else - *p_menu = osd_MenuNew( *p_menu, &path[0], 0, 0 ); - } - - if( !*p_menu ) - goto error; - - /* read successive lines */ - while( !feof( fd ) ) - { - osd_state_t *p_state_current = NULL; /* button state currently processed */ - osd_state_t *p_state_prev = NULL; /* previous state processed button */ - - char cmd[25] = ""; - char action[25] = ""; - char state[25] = ""; - char file[256] = ""; - char path[512] = ""; - int i_x = 0; - int i_y = 0; - - result = fscanf( fd, "%24s %24s (%d,%d)", &cmd[0], &action[0], &i_x, &i_y ); - if( result == 0 ) - goto error; - if( strncmp( &cmd[0], "action", 6 ) != 0 ) - break; - msg_Dbg( p_this, " + %s hotkey=%s (%d,%d)", &cmd[0], &action[0], i_x, i_y ); - - p_prev = p_current; - p_current = osd_ButtonNew( &action[0], i_x, i_y ); - if( !p_current ) - goto error; - - if( p_prev ) - p_prev->p_next = p_current; - else - (*p_menu)->p_button = p_current; - p_current->p_prev = p_prev; - - /* parse all states */ - while( !feof( fd ) ) - { - char type[25] = ""; - - result = fscanf( fd, "\t%24s", &state[0] ); - if( result == 0 ) - goto error; - - /* FIXME: We only parse one level deep now */ - if( strncmp( &state[0], "action", 6 ) == 0 ) - { - osd_button_t *p_up = NULL; - - result = fscanf( fd, "%24s (%d,%d)", &action[0], &i_x, &i_y ); - if( result == 0 ) - goto error; - /* create new button */ - p_up = osd_ButtonNew( &action[0], i_x, i_y ); - if( !p_up ) - goto error; - /* Link to list */ - p_up->p_down = p_current; - p_current->p_up = p_up; - msg_Dbg( p_this, " + (menu up) hotkey=%s (%d,%d)", &action[0], i_x, i_y ); - /* Parse type state */ - result = fscanf( fd, "\t%24s %24s", &cmd[0], &type[0] ); - if( result == 0 ) - goto error; - if( strncmp( &cmd[0], "type", 4 ) == 0 ) - { - if( strncmp( &type[0], "volume", 6 ) == 0 ) - { - (*p_menu)->p_state->p_volume = p_up; - msg_Dbg( p_this, " + type=%s", &type[0] ); - } - } - /* Parse range state */ - result = fscanf( fd, "\t%24s", &state[0] ); - if( result == 0 ) - goto error; - /* Parse the range state */ - if( strncmp( &state[0], "range", 5 ) == 0 ) - { - osd_state_t *p_range_current = NULL; /* range state currently processed */ - osd_state_t *p_range_prev = NULL; /* previous state processed range */ - int i_index = 0; - - p_up->b_range = VLC_TRUE; - - result = fscanf( fd, "\t%24s", &action[0] ); - if( result == 0 ) - goto error; - - result = fscanf( fd, "\t%d", &i_index ); - if( result == 0 ) - goto error; - - msg_Dbg( p_this, " + (menu up) hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] ); - - if( p_up->psz_action_down ) free( p_up->psz_action_down ); - p_up->psz_action_down = strdup( &action[0] ); - - /* Parse range contstruction : - * range - * - * - * - * end - */ - while( !feof( fd ) ) - { - result = fscanf( fd, "\t%255s", &file[0] ); - if( result == 0 ) - goto error; - if( strncmp( &file[0], "end", 3 ) == 0 ) - break; - - p_range_prev = p_range_current; - - if( (*p_menu)->psz_path ) - { - size_t i_path_size = strlen( (*p_menu)->psz_path ); - size_t i_file_size = strlen( &file[0] ); - - strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); - strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); - path[ i_path_size + i_file_size ] = '\0'; - - p_range_current = osd_StateNew( p_this, &path[0], "pressed" ); - } - else /* absolute paths are used. */ - p_range_current = osd_StateNew( p_this, &file[0], "pressed" ); - - if( !p_range_current || !p_range_current->p_pic ) - goto error; - - /* increment the number of ranges for this button */ - p_up->i_ranges++; - - if( p_range_prev ) - p_range_prev->p_next = p_range_current; - else - p_up->p_states = p_range_current; - p_range_current->p_prev = p_range_prev; - - msg_Dbg( p_this, " |- range=%d, file=%s%s", - p_up->i_ranges, - (*p_menu)->psz_path, &file[0] ); - } - if( i_index > 0 ) - { - osd_state_t *p_range = NULL; - - /* Find the default index for state range */ - p_range = p_up->p_states; - while( (--i_index > 0) && p_range->p_next ) - { - osd_state_t *p_temp = NULL; - p_temp = p_range->p_next; - p_range = p_temp; - } - p_up->p_current_state = p_range; - } - else p_up->p_current_state = p_up->p_states; - - } - result = fscanf( fd, "\t%24s", &state[0] ); - if( result == 0 ) - goto error; - if( strncmp( &state[0], "end", 3 ) != 0 ) - goto error; - - /* Continue at the beginning of the while() */ - continue; - } - - /* Parse the range state */ - if( strncmp( &state[0], "range", 5 ) == 0 ) - { - osd_state_t *p_range_current = NULL; /* range state currently processed */ - osd_state_t *p_range_prev = NULL; /* previous state processed range */ - int i_index = 0; - - p_current->b_range = VLC_TRUE; - - result = fscanf( fd, "\t%24s", &action[0] ); - if( result == 0 ) - goto error; - - result = fscanf( fd, "\t%d", &i_index ); - if( result == 0 ) - goto error; - - msg_Dbg( p_this, " + hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] ); - if( p_current->psz_action_down ) free( p_current->psz_action_down ); - p_current->psz_action_down = strdup( &action[0] ); - - /* Parse range contstruction : - * range - * - * - * - * end - */ - while( !feof( fd ) ) - { - result = fscanf( fd, "\t%255s", &file[0] ); - if( result == 0 ) - goto error; - if( strncmp( &file[0], "end", 3 ) == 0 ) - break; - - p_range_prev = p_range_current; - - if( (*p_menu)->psz_path ) - { - size_t i_path_size = strlen( (*p_menu)->psz_path ); - size_t i_file_size = strlen( &file[0] ); - - strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); - strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); - path[ i_path_size + i_file_size ] = '\0'; - - p_range_current = osd_StateNew( p_this, &path[0], "pressed" ); - } - else /* absolute paths are used. */ - p_range_current = osd_StateNew( p_this, &file[0], "pressed" ); - - if( !p_range_current || !p_range_current->p_pic ) - goto error; - - /* increment the number of ranges for this button */ - p_current->i_ranges++; - - if( p_range_prev ) - p_range_prev->p_next = p_range_current; - else - p_current->p_states = p_range_current; - p_range_current->p_prev = p_range_prev; - - msg_Dbg( p_this, " |- range=%d, file=%s%s", - p_current->i_ranges, - (*p_menu)->psz_path, &file[0] ); - } - if( i_index > 0 ) - { - osd_state_t *p_range = NULL; - - /* Find the default index for state range */ - p_range = p_current->p_states; - while( (--i_index > 0) && p_range->p_next ) - { - osd_state_t *p_temp = NULL; - p_temp = p_range->p_next; - p_range = p_temp; - } - p_current->p_current_state = p_range; - } - else p_current->p_current_state = p_current->p_states; - /* Continue at the beginning of the while() */ - continue; - } - if( strncmp( &state[0], "end", 3 ) == 0 ) - break; - - result = fscanf( fd, "\t%255s", &file[0] ); - if( result == 0 ) - goto error; - - p_state_prev = p_state_current; - - if( ( strncmp( ppsz_button_states[0], &state[0], strlen(ppsz_button_states[0]) ) != 0 ) && - ( strncmp( ppsz_button_states[1], &state[0], strlen(ppsz_button_states[1]) ) != 0 ) && - ( strncmp( ppsz_button_states[2], &state[0], strlen(ppsz_button_states[2]) ) != 0 ) ) - { - msg_Err( p_this, "invalid button state %s for button %s expected %d: unselect, select or pressed)", - &state[0], &action[0], strlen(&state[0])); - goto error; - } - - if( (*p_menu)->psz_path ) - { - size_t i_path_size = strlen( (*p_menu)->psz_path ); - size_t i_file_size = strlen( &file[0] ); - - strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); - strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); - path[ i_path_size + i_file_size ] = '\0'; - - p_state_current = osd_StateNew( p_this, &path[0], &state[0] ); - } - else /* absolute paths are used. */ - p_state_current = osd_StateNew( p_this, &file[0], &state[0] ); - - if( !p_state_current || !p_state_current->p_pic ) - goto error; - - if( p_state_prev ) - p_state_prev->p_next = p_state_current; - else - p_current->p_states = p_state_current; - p_state_current->p_prev = p_state_prev; - - msg_Dbg( p_this, " |- state=%s, file=%s%s", &state[0], (*p_menu)->psz_path, &file[0] ); - } - p_current->p_current_state = p_current->p_states; - } - - /* Find the last button and store its pointer. - * The OSD menu behaves like a roundrobin list. - */ - p_current = (*p_menu)->p_button; - while( p_current && p_current->p_next ) - { - osd_button_t *p_temp = NULL; - p_temp = p_current->p_next; - p_current = p_temp; - } - (*p_menu)->p_last_button = p_current; - fclose( fd ); - return 0; - -#undef MAX_FILE_PATH -error: - msg_Err( p_this, "parsing file failed (returned %d)", result ); - fclose( fd ); - return 1; -} - -/***************************************************************************** - * osd_ConfigUnload: Load and parse osd text configurationfile - *****************************************************************************/ -void osd_ConfigUnload( vlc_object_t *p_this, osd_menu_t **p_osd) -{ - msg_Dbg( p_this, "unloading OSD menu structure" ); - osd_MenuFree( p_this, *p_osd ); -} +/***************************************************************************** + * osd_parser.c - The OSD Menu parser core code. + ***************************************************************************** + * Copyright (C) 2005 M2X + * $Id$ + * + * Authors: Jean-Paul Saman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include +#include + +#include +#include +#include + +#include +#include +#include + + +#undef OSD_MENU_DEBUG + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static const char *ppsz_button_states[] = { "unselect", "select", "pressed" }; + +/* OSD Menu structure support routines */ +static osd_menu_t *osd_MenuNew( osd_menu_t *, const char *, int, int ); +static osd_button_t *osd_ButtonNew( const char *, int, int ); +static osd_state_t *osd_StateNew( vlc_object_t *, const char *, const char * ); + +static void osd_MenuFree ( vlc_object_t *, osd_menu_t * ); +static void osd_ButtonFree( vlc_object_t *, osd_button_t * ); +static void osd_StatesFree( vlc_object_t *, osd_state_t * ); + +static picture_t *osd_LoadImage( vlc_object_t *, const char *); + +/***************************************************************************** + * osd_LoadImage: loads the logo image into memory + *****************************************************************************/ +static picture_t *osd_LoadImage( vlc_object_t *p_this, const char *psz_filename ) +{ + picture_t *p_pic = NULL; + image_handler_t *p_image; + video_format_t fmt_in = {0}, fmt_out = {0}; + + fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); + p_image = image_HandlerCreate( p_this ); + if( p_image ) + { + p_pic = image_ReadUrl( p_image, psz_filename, &fmt_in, &fmt_out ); + image_HandlerDelete( p_image ); +#if 0 + p_pic = osd_YuvaYuvp( p_this, p_pic ); +#endif + } + else msg_Err( p_this, "unable to handle this chroma" ); + + return p_pic; +} + +/***************************************************************************** + * Create a new Menu structure + *****************************************************************************/ +static osd_menu_t *osd_MenuNew( osd_menu_t *p_menu, const char *psz_path, int i_x, int i_y ) +{ + if( !p_menu ) return NULL; + + p_menu->p_state = (osd_menu_state_t *) malloc( sizeof( osd_menu_state_t ) ); + if( !p_menu->p_state ) + msg_Err( p_menu, "memory allocation for OSD Menu state failed." ); + + if( psz_path != NULL ) + p_menu->psz_path = strdup( psz_path ); + else + p_menu->psz_path = NULL; + p_menu->i_x = i_x; + p_menu->i_y = i_y; + + return p_menu; +} + +/***************************************************************************** + * Free the menu + *****************************************************************************/ +static void osd_MenuFree( vlc_object_t *p_this, osd_menu_t *p_menu ) +{ + msg_Dbg( p_this, "freeing menu" ); + osd_ButtonFree( p_this, p_menu->p_button ); + p_menu->p_button = NULL; + p_menu->p_last_button = NULL; + if( p_menu->psz_path ) free( p_menu->psz_path ); + p_menu->psz_path = NULL; + if( p_menu->p_state ) free( p_menu->p_state ); + p_menu->p_state = NULL; +} + +/***************************************************************************** + * Create a new button + *****************************************************************************/ +static osd_button_t *osd_ButtonNew( const char *psz_action, int i_x, int i_y ) +{ + osd_button_t *p_button = NULL; + p_button = (osd_button_t*) malloc( sizeof(osd_button_t) ); + if( !p_button ) + return NULL; + + memset( p_button, 0, sizeof(osd_button_t) ); + p_button->psz_action = strdup(psz_action); + p_button->psz_action_down = NULL; + p_button->p_feedback = NULL; + p_button->i_x = i_x; + p_button->i_y = i_y; + + return p_button; +} + +/***************************************************************************** + * Free a button + *****************************************************************************/ +static void osd_ButtonFree( vlc_object_t *p_this, osd_button_t *p_button ) +{ + osd_button_t *p_current = p_button; + osd_button_t *p_next = NULL; + osd_button_t *p_prev = NULL; + + /* First walk to the end. */ + while( p_current->p_next ) + { + p_next = p_current->p_next; + p_current = p_next; + } + /* Then free end first and walk to the start. */ + while( p_current->p_prev ) + { + msg_Dbg( p_this, "+ freeing button %s [%p]", p_current->psz_action, p_current ); + p_prev = p_current->p_prev; + p_current = p_prev; + if( p_current->p_next ) + { + if( p_current->p_next->psz_name ) + free( p_current->p_next->psz_name ); + if( p_current->p_next->psz_action ) + free( p_current->p_next->psz_action ); + if( p_current->p_next->psz_action_down ) + free( p_current->p_next->psz_action_down ); + if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) + free( p_current->p_feedback->p_data_orig ); + if( p_current->p_feedback ) + free( p_current->p_feedback ); + + p_current->p_next->psz_action_down = NULL; + p_current->p_next->psz_action = NULL; + p_current->p_next->psz_name = NULL; + p_current->p_feedback = NULL; + + /* Free all states first */ + if( p_current->p_next->p_states ) + osd_StatesFree( p_this, p_current->p_next->p_states ); + p_current->p_next->p_states = NULL; + if( p_current->p_next) free( p_current->p_next ); + p_current->p_next = NULL; + } + + if( p_current->p_up ) + { + if( p_current->p_up->psz_name ) + free( p_current->p_up->psz_name ); + if( p_current->p_up->psz_action ) + free( p_current->p_up->psz_action ); + if( p_current->p_up->psz_action_down ) + free( p_current->p_up->psz_action_down ); + if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) + free( p_current->p_feedback->p_data_orig ); + if( p_current->p_feedback ) + free( p_current->p_feedback ); + + p_current->p_up->psz_action_down = NULL; + p_current->p_up->psz_action = NULL; + p_current->p_up->psz_name = NULL; + p_current->p_feedback = NULL; + + /* Free all states first */ + if( p_current->p_up->p_states ) + osd_StatesFree( p_this, p_current->p_up->p_states ); + p_current->p_up->p_states = NULL; + if( p_current->p_up ) free( p_current->p_up ); + p_current->p_up = NULL; + } + } + /* Free the last one. */ + if( p_button ) + { + msg_Dbg( p_this, "+ freeing button %s [%p]", p_button->psz_action, p_button ); + if( p_button->psz_name ) free( p_button->psz_name ); + if( p_button->psz_action ) free( p_button->psz_action ); + if( p_button->psz_action_down ) free( p_button->psz_action_down ); + if( p_current->p_feedback && p_current->p_feedback->p_data_orig ) + free( p_current->p_feedback->p_data_orig ); + if( p_current->p_feedback ) + free( p_current->p_feedback ); + + p_button->psz_name = NULL; + p_button->psz_action = NULL; + p_button->psz_action_down = NULL; + p_current->p_feedback = NULL; + + if( p_button->p_states ) + osd_StatesFree( p_this, p_button->p_states ); + p_button->p_states = NULL; + free( p_button ); + p_button = NULL; + } +} + +/***************************************************************************** + * Create a new state image + *****************************************************************************/ +static osd_state_t *osd_StateNew( vlc_object_t *p_this, const char *psz_file, const char *psz_state ) +{ + osd_state_t *p_state = NULL; + p_state = (osd_state_t*) malloc( sizeof(osd_state_t) ); + if( !p_state ) + return NULL; + + memset( p_state, 0, sizeof(osd_state_t) ); + p_state->p_pic = osd_LoadImage( p_this, psz_file ); + + if( psz_state ) + { + p_state->psz_state = strdup( psz_state ); + if( strncmp( ppsz_button_states[0], psz_state, strlen(ppsz_button_states[0]) ) == 0 ) + p_state->i_state = OSD_BUTTON_UNSELECT; + else if( strncmp( ppsz_button_states[1], psz_state, strlen(ppsz_button_states[1]) ) == 0 ) + p_state->i_state = OSD_BUTTON_SELECT; + else if( strncmp( ppsz_button_states[2], psz_state, strlen(ppsz_button_states[2]) ) == 0 ) + p_state->i_state = OSD_BUTTON_PRESSED; + } + return p_state; +} + +/***************************************************************************** + * Free state images + *****************************************************************************/ +static void osd_StatesFree( vlc_object_t *p_this, osd_state_t *p_states ) +{ + osd_state_t *p_state = p_states; + osd_state_t *p_next = NULL; + osd_state_t *p_prev = NULL; + + while( p_state->p_next ) + { + p_next = p_state->p_next; + p_state = p_next; + } + /* Then free end first and walk to the start. */ + while( p_state->p_prev ) + { + msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_state ); + p_prev = p_state->p_prev; + p_state = p_prev; + if( p_state->p_next ) + { + if( p_state->p_next->p_pic && p_state->p_next->p_pic->p_data_orig ) + free( p_state->p_next->p_pic->p_data_orig ); + if( p_state->p_next->p_pic ) free( p_state->p_next->p_pic ); + p_state->p_next->p_pic = NULL; + if( p_state->p_next->psz_state ) free( p_state->p_next->psz_state ); + p_state->p_next->psz_state = NULL; + free( p_state->p_next ); + p_state->p_next = NULL; + } + } + /* Free the last one. */ + if( p_states ) + { + msg_Dbg( p_this, " |- freeing state %s [%p]", p_state->psz_state, p_states ); + if( p_states->p_pic && p_states->p_pic->p_data_orig ) + free( p_states->p_pic->p_data_orig ); + if( p_states->p_pic ) free( p_states->p_pic ); + p_states->p_pic = NULL; + if( p_state->psz_state ) free( p_state->psz_state ); + p_state->psz_state = NULL; + free( p_states ); + p_states = NULL; + } +} + +/***************************************************************************** + * osd_ConfigLoader: Load and parse osd text configurationfile + *****************************************************************************/ +int osd_ConfigLoader( vlc_object_t *p_this, const char *psz_file, + osd_menu_t **p_menu ) +{ + osd_button_t *p_current = NULL; /* button currently processed */ + osd_button_t *p_prev = NULL; /* previous processed button */ + +#define MAX_FILE_PATH 256 + FILE *fd = NULL; + int result = 0; + + msg_Dbg( p_this, "opening osd definition file %s", psz_file ); + fd = fopen( psz_file, "r" ); + if( !fd ) + { + msg_Err( p_this, "failed opening osd definition file %s", psz_file ); + return VLC_EGENERIC; + } + + /* Read first line */ + if( !feof( fd ) ) + { + char action[25] = ""; + char path[MAX_FILE_PATH] = ""; + char *psz_path = NULL; + size_t i_len = 0; + + /* override images path ? */ + psz_path = config_GetPsz( p_this, "osdmenu-file-path" ); + if( psz_path == NULL ) + { + result = fscanf(fd, "%24s %255s", &action[0], &path[0] ); + } + else + { + /* psz_path is not null and therefor &path[0] cannot be NULL + * it might be null terminated. + */ + strncpy( &path[0], psz_path, MAX_FILE_PATH ); + free( psz_path ); + psz_path = NULL; + } + /* NULL terminate before asking the length of path[] */ + path[MAX_FILE_PATH-1] = '\0'; + i_len = strlen(&path[0]); + if( i_len == MAX_FILE_PATH ) + i_len--; /* truncate to prevent buffer overflow */ +#if defined(WIN32) || defined(UNDER_CE) + if( (i_len > 0) && path[i_len] != '\\' ) + path[i_len] = '\\'; +#else + if( (i_len > 0) && path[i_len] != '/' ) + path[i_len] = '/'; +#endif + path[i_len+1] = '\0'; + if( result == 0 || result == EOF ) + goto error; + msg_Dbg( p_this, "%s=%s", &action[0], &path[0] ); + + if( i_len == 0 ) + *p_menu = osd_MenuNew( *p_menu, NULL, 0, 0 ); + else + *p_menu = osd_MenuNew( *p_menu, &path[0], 0, 0 ); + } + + if( !*p_menu ) + goto error; + + /* read successive lines */ + while( !feof( fd ) ) + { + osd_state_t *p_state_current = NULL; /* button state currently processed */ + osd_state_t *p_state_prev = NULL; /* previous state processed button */ + + char cmd[25] = ""; + char action[25] = ""; + char state[25] = ""; + char file[256] = ""; + char path[512] = ""; + int i_x = 0; + int i_y = 0; + + result = fscanf( fd, "%24s %24s (%d,%d)", &cmd[0], &action[0], &i_x, &i_y ); + if( result == 0 ) + goto error; + if( strncmp( &cmd[0], "action", 6 ) != 0 ) + break; + msg_Dbg( p_this, " + %s hotkey=%s (%d,%d)", &cmd[0], &action[0], i_x, i_y ); + + p_prev = p_current; + p_current = osd_ButtonNew( &action[0], i_x, i_y ); + if( !p_current ) + goto error; + + if( p_prev ) + p_prev->p_next = p_current; + else + (*p_menu)->p_button = p_current; + p_current->p_prev = p_prev; + + /* parse all states */ + while( !feof( fd ) ) + { + char type[25] = ""; + + result = fscanf( fd, "\t%24s", &state[0] ); + if( result == 0 ) + goto error; + + /* FIXME: We only parse one level deep now */ + if( strncmp( &state[0], "action", 6 ) == 0 ) + { + osd_button_t *p_up = NULL; + + result = fscanf( fd, "%24s (%d,%d)", &action[0], &i_x, &i_y ); + if( result == 0 ) + goto error; + /* create new button */ + p_up = osd_ButtonNew( &action[0], i_x, i_y ); + if( !p_up ) + goto error; + /* Link to list */ + p_up->p_down = p_current; + p_current->p_up = p_up; + msg_Dbg( p_this, " + (menu up) hotkey=%s (%d,%d)", &action[0], i_x, i_y ); + /* Parse type state */ + result = fscanf( fd, "\t%24s %24s", &cmd[0], &type[0] ); + if( result == 0 ) + goto error; + if( strncmp( &cmd[0], "type", 4 ) == 0 ) + { + if( strncmp( &type[0], "volume", 6 ) == 0 ) + { + (*p_menu)->p_state->p_volume = p_up; + msg_Dbg( p_this, " + type=%s", &type[0] ); + } + } + /* Parse range state */ + result = fscanf( fd, "\t%24s", &state[0] ); + if( result == 0 ) + goto error; + /* Parse the range state */ + if( strncmp( &state[0], "range", 5 ) == 0 ) + { + osd_state_t *p_range_current = NULL; /* range state currently processed */ + osd_state_t *p_range_prev = NULL; /* previous state processed range */ + int i_index = 0; + + p_up->b_range = VLC_TRUE; + + result = fscanf( fd, "\t%24s", &action[0] ); + if( result == 0 ) + goto error; + + result = fscanf( fd, "\t%d", &i_index ); + if( result == 0 ) + goto error; + + msg_Dbg( p_this, " + (menu up) hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] ); + + if( p_up->psz_action_down ) free( p_up->psz_action_down ); + p_up->psz_action_down = strdup( &action[0] ); + + /* Parse range contstruction : + * range + * + * + * + * end + */ + while( !feof( fd ) ) + { + result = fscanf( fd, "\t%255s", &file[0] ); + if( result == 0 ) + goto error; + if( strncmp( &file[0], "end", 3 ) == 0 ) + break; + + p_range_prev = p_range_current; + + if( (*p_menu)->psz_path ) + { + size_t i_path_size = strlen( (*p_menu)->psz_path ); + size_t i_file_size = strlen( &file[0] ); + + strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); + strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); + path[ i_path_size + i_file_size ] = '\0'; + + p_range_current = osd_StateNew( p_this, &path[0], "pressed" ); + } + else /* absolute paths are used. */ + p_range_current = osd_StateNew( p_this, &file[0], "pressed" ); + + if( !p_range_current || !p_range_current->p_pic ) + goto error; + + /* increment the number of ranges for this button */ + p_up->i_ranges++; + + if( p_range_prev ) + p_range_prev->p_next = p_range_current; + else + p_up->p_states = p_range_current; + p_range_current->p_prev = p_range_prev; + + msg_Dbg( p_this, " |- range=%d, file=%s%s", + p_up->i_ranges, + (*p_menu)->psz_path, &file[0] ); + } + if( i_index > 0 ) + { + osd_state_t *p_range = NULL; + + /* Find the default index for state range */ + p_range = p_up->p_states; + while( (--i_index > 0) && p_range->p_next ) + { + osd_state_t *p_temp = NULL; + p_temp = p_range->p_next; + p_range = p_temp; + } + p_up->p_current_state = p_range; + } + else p_up->p_current_state = p_up->p_states; + + } + result = fscanf( fd, "\t%24s", &state[0] ); + if( result == 0 ) + goto error; + if( strncmp( &state[0], "end", 3 ) != 0 ) + goto error; + + /* Continue at the beginning of the while() */ + continue; + } + + /* Parse the range state */ + if( strncmp( &state[0], "range", 5 ) == 0 ) + { + osd_state_t *p_range_current = NULL; /* range state currently processed */ + osd_state_t *p_range_prev = NULL; /* previous state processed range */ + int i_index = 0; + + p_current->b_range = VLC_TRUE; + + result = fscanf( fd, "\t%24s", &action[0] ); + if( result == 0 ) + goto error; + + result = fscanf( fd, "\t%d", &i_index ); + if( result == 0 ) + goto error; + + msg_Dbg( p_this, " + hotkey down %s, file=%s%s", &action[0], (*p_menu)->psz_path, &file[0] ); + if( p_current->psz_action_down ) free( p_current->psz_action_down ); + p_current->psz_action_down = strdup( &action[0] ); + + /* Parse range contstruction : + * range + * + * + * + * end + */ + while( !feof( fd ) ) + { + result = fscanf( fd, "\t%255s", &file[0] ); + if( result == 0 ) + goto error; + if( strncmp( &file[0], "end", 3 ) == 0 ) + break; + + p_range_prev = p_range_current; + + if( (*p_menu)->psz_path ) + { + size_t i_path_size = strlen( (*p_menu)->psz_path ); + size_t i_file_size = strlen( &file[0] ); + + strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); + strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); + path[ i_path_size + i_file_size ] = '\0'; + + p_range_current = osd_StateNew( p_this, &path[0], "pressed" ); + } + else /* absolute paths are used. */ + p_range_current = osd_StateNew( p_this, &file[0], "pressed" ); + + if( !p_range_current || !p_range_current->p_pic ) + goto error; + + /* increment the number of ranges for this button */ + p_current->i_ranges++; + + if( p_range_prev ) + p_range_prev->p_next = p_range_current; + else + p_current->p_states = p_range_current; + p_range_current->p_prev = p_range_prev; + + msg_Dbg( p_this, " |- range=%d, file=%s%s", + p_current->i_ranges, + (*p_menu)->psz_path, &file[0] ); + } + if( i_index > 0 ) + { + osd_state_t *p_range = NULL; + + /* Find the default index for state range */ + p_range = p_current->p_states; + while( (--i_index > 0) && p_range->p_next ) + { + osd_state_t *p_temp = NULL; + p_temp = p_range->p_next; + p_range = p_temp; + } + p_current->p_current_state = p_range; + } + else p_current->p_current_state = p_current->p_states; + /* Continue at the beginning of the while() */ + continue; + } + if( strncmp( &state[0], "end", 3 ) == 0 ) + break; + + result = fscanf( fd, "\t%255s", &file[0] ); + if( result == 0 ) + goto error; + + p_state_prev = p_state_current; + + if( ( strncmp( ppsz_button_states[0], &state[0], strlen(ppsz_button_states[0]) ) != 0 ) && + ( strncmp( ppsz_button_states[1], &state[0], strlen(ppsz_button_states[1]) ) != 0 ) && + ( strncmp( ppsz_button_states[2], &state[0], strlen(ppsz_button_states[2]) ) != 0 ) ) + { + msg_Err( p_this, "invalid button state %s for button %s expected %d: unselect, select or pressed)", + &state[0], &action[0], strlen(&state[0])); + goto error; + } + + if( (*p_menu)->psz_path ) + { + size_t i_path_size = strlen( (*p_menu)->psz_path ); + size_t i_file_size = strlen( &file[0] ); + + strncpy( &path[0], (*p_menu)->psz_path, i_path_size ); + strncpy( &path[i_path_size], &file[0], 512 - (i_path_size + i_file_size) ); + path[ i_path_size + i_file_size ] = '\0'; + + p_state_current = osd_StateNew( p_this, &path[0], &state[0] ); + } + else /* absolute paths are used. */ + p_state_current = osd_StateNew( p_this, &file[0], &state[0] ); + + if( !p_state_current || !p_state_current->p_pic ) + goto error; + + if( p_state_prev ) + p_state_prev->p_next = p_state_current; + else + p_current->p_states = p_state_current; + p_state_current->p_prev = p_state_prev; + + msg_Dbg( p_this, " |- state=%s, file=%s%s", &state[0], (*p_menu)->psz_path, &file[0] ); + } + p_current->p_current_state = p_current->p_states; + } + + /* Find the last button and store its pointer. + * The OSD menu behaves like a roundrobin list. + */ + p_current = (*p_menu)->p_button; + while( p_current && p_current->p_next ) + { + osd_button_t *p_temp = NULL; + p_temp = p_current->p_next; + p_current = p_temp; + } + (*p_menu)->p_last_button = p_current; + fclose( fd ); + return 0; + +#undef MAX_FILE_PATH +error: + msg_Err( p_this, "parsing file failed (returned %d)", result ); + fclose( fd ); + return 1; +} + +/***************************************************************************** + * osd_ConfigUnload: Load and parse osd text configurationfile + *****************************************************************************/ +void osd_ConfigUnload( vlc_object_t *p_this, osd_menu_t **p_osd) +{ + msg_Dbg( p_this, "unloading OSD menu structure" ); + osd_MenuFree( p_this, *p_osd ); +} -- 2.39.2