Orb/Doxygen/src/lodepng.cpp
author Michel Szarindar <Michel.Szarindar@Nokia.com>
Thu, 18 Mar 2010 18:26:18 +0000
changeset 1 82f11024044a
parent 0 42188c7ea2d9
permissions -rw-r--r--
Contribution of a new version of ORB and CXX DITA plug-in bug 1461 bug 1621 bug 1962
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     1
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     2
LodePNG version 20080927
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     3
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     4
Copyright (c) 2005-2008 Lode Vandevenne
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     5
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     6
This software is provided 'as-is', without any express or implied
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     7
warranty. In no event will the authors be held liable for any damages
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     8
arising from the use of this software.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
     9
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    10
Permission is granted to anyone to use this software for any purpose,
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    11
including commercial applications, and to alter it and redistribute it
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    12
freely, subject to the following restrictions:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    13
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    14
    1. The origin of this software must not be misrepresented; you must not
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    15
    claim that you wrote the original software. If you use this software
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    16
    in a product, an acknowledgment in the product documentation would be
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    17
    appreciated but is not required.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    18
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    19
    2. Altered source versions must be plainly marked as such, and must not be
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    20
    misrepresented as being the original software.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    21
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    22
    3. This notice may not be removed or altered from any source
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    23
    distribution.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    24
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    25
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    26
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    27
The manual and changelog can be found in the header file "lodepng.h"
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    28
You are free to name this file lodepng.cpp or lodepng.c depending on your usage.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    29
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    30
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    31
#include "lodepng.h"
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    32
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    33
#define VERSION_STRING "20080927"
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    34
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    35
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    36
/* / Tools For C                                                            / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    37
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    38
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    39
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    40
About these tools (vector, uivector, ucvector and string):
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    41
-LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    42
-The string tools are made to avoid problems with compilers that declare things like strncat as deprecated.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    43
-They're not used in the interface, only internally in this file, so all their functions are made static.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    44
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    45
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    46
#ifdef LODEPNG_COMPILE_ZLIB
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    47
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    48
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    49
typedef struct vector /*this one is used only by the deflate compressor*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    50
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    51
  void* data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    52
  size_t size; /*in groups of bytes depending on type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    53
  size_t allocsize; /*in bytes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    54
  unsigned typesize; /*sizeof the type you store in data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    55
} vector;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    56
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    57
static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    58
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    59
  if(size * p->typesize > p->allocsize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    60
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    61
    size_t newsize = size * p->typesize * 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    62
    void* data = realloc(p->data, newsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    63
    if(data)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    64
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    65
      p->allocsize = newsize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    66
      p->data = data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    67
      p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    68
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    69
    else return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    70
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    71
  else p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    72
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    73
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    74
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    75
static unsigned vector_resized(vector* p, size_t size, void dtor(void*)) /*resize and use destructor on elements if it gets smaller*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    76
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    77
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    78
  if(size < p->size) for(i = size; i < p->size; i++) dtor(&((char*)(p->data))[i * p->typesize]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    79
  return vector_resize(p, size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    80
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    81
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    82
static void vector_cleanup(void* p)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    83
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    84
  ((vector*)p)->size = ((vector*)p)->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    85
  free(((vector*)p)->data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    86
  ((vector*)p)->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    87
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    88
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    89
static void vector_cleanupd(vector* p, void dtor(void*)) /*clear and use destructor on elements*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    90
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    91
  vector_resized(p, 0, dtor);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    92
  vector_cleanup(p);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    93
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    94
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    95
static void vector_init(vector* p, unsigned typesize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    96
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    97
  p->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    98
  p->size = p->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
    99
  p->typesize = typesize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   100
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   101
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   102
static void vector_swap(vector* p, vector* q) /*they're supposed to have the same typesize*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   103
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   104
  size_t tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   105
  void* tmpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   106
  tmp = p->size; p->size = q->size; q->size = tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   107
  tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   108
  tmpp = p->data; p->data = q->data; q->data = tmpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   109
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   110
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   111
static void* vector_get(vector* p, size_t index)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   112
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   113
  return &((char*)p->data)[index * p->typesize];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   114
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   115
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   116
#endif /*LODEPNG_COMPILE_ZLIB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   117
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   118
/* /////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   119
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   120
#ifdef LODEPNG_COMPILE_ZLIB
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   121
typedef struct uivector
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   122
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   123
  unsigned* data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   124
  size_t size; /*size in number of unsigned longs*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   125
  size_t allocsize; /*allocated size in bytes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   126
} uivector;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   127
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   128
static void uivector_cleanup(void* p)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   129
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   130
  ((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   131
  free(((uivector*)p)->data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   132
  ((uivector*)p)->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   133
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   134
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   135
static unsigned uivector_resize(uivector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   136
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   137
  if(size * sizeof(unsigned) > p->allocsize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   138
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   139
    size_t newsize = size * sizeof(unsigned) * 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   140
    void* data = realloc(p->data, newsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   141
    if(data)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   142
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   143
      p->allocsize = newsize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   144
      p->data = (unsigned*)data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   145
      p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   146
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   147
    else return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   148
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   149
  else p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   150
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   151
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   152
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   153
static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) /*resize and give all new elements the value*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   154
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   155
  size_t oldsize = p->size, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   156
  if(!uivector_resize(p, size)) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   157
  for(i = oldsize; i < size; i++) p->data[i] = value;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   158
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   159
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   160
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   161
static void uivector_init(uivector* p)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   162
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   163
  p->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   164
  p->size = p->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   165
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   166
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   167
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   168
static unsigned uivector_push_back(uivector* p, unsigned c) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   169
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   170
  if(!uivector_resize(p, p->size + 1)) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   171
  p->data[p->size - 1] = c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   172
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   173
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   174
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   175
static unsigned uivector_copy(uivector* p, const uivector* q) /*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   176
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   177
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   178
  if(!uivector_resize(p, q->size)) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   179
  for(i = 0; i < q->size; i++) p->data[i] = q->data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   180
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   181
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   182
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   183
static void uivector_swap(uivector* p, uivector* q)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   184
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   185
  size_t tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   186
  unsigned* tmpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   187
  tmp = p->size; p->size = q->size; q->size = tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   188
  tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   189
  tmpp = p->data; p->data = q->data; q->data = tmpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   190
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   191
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   192
#endif /*LODEPNG_COMPILE_ZLIB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   193
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   194
/* /////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   195
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   196
typedef struct ucvector
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   197
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   198
  unsigned char* data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   199
  size_t size; /*used size*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   200
  size_t allocsize; /*allocated size*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   201
} ucvector;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   202
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   203
static void ucvector_cleanup(void* p)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   204
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   205
  ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   206
  free(((ucvector*)p)->data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   207
  ((ucvector*)p)->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   208
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   209
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   210
static unsigned ucvector_resize(ucvector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   211
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   212
  if(size * sizeof(unsigned) > p->allocsize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   213
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   214
    size_t newsize = size * sizeof(unsigned) * 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   215
    void* data = realloc(p->data, newsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   216
    if(data)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   217
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   218
      p->allocsize = newsize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   219
      p->data = (unsigned char*)data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   220
      p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   221
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   222
    else return 0; /*error: not enough memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   223
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   224
  else p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   225
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   226
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   227
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   228
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   229
#ifdef LODEPNG_COMPILE_PNG
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   230
static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) /*resize and give all new elements the value*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   231
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   232
  size_t oldsize = p->size, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   233
  if(!ucvector_resize(p, size)) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   234
  for(i = oldsize; i < size; i++) p->data[i] = value;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   235
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   236
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   237
#endif /*LODEPNG_COMPILE_PNG*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   238
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   239
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   240
static void ucvector_init(ucvector* p)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   241
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   242
  p->data = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   243
  p->size = p->allocsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   244
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   245
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   246
#ifdef LODEPNG_COMPILE_ZLIB
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   247
/*you can both convert from vector to buffer&size and vica versa*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   248
static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   249
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   250
  p->data = buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   251
  p->allocsize = p->size = size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   252
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   253
#endif /*LODEPNG_COMPILE_ZLIB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   254
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   255
static unsigned ucvector_push_back(ucvector* p, unsigned char c) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   256
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   257
  if(!ucvector_resize(p, p->size + 1)) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   258
  p->data[p->size - 1] = c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   259
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   260
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   261
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   262
/* /////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   263
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   264
#ifdef LODEPNG_COMPILE_PNG
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   265
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   266
static unsigned string_resize(char** out, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   267
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   268
  char* data = (char*)realloc(*out, size + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   269
  if(data)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   270
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   271
    data[size] = 0; /*null termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   272
    *out = data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   273
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   274
  return data != 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   275
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   276
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   277
static void string_init(char** out) /*init a {char*, size_t} pair for use as string*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   278
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   279
  *out = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   280
  string_resize(out, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   281
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   282
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   283
static void string_cleanup(char** out) /*free the above pair again*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   284
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   285
  free(*out);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   286
  *out = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   287
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   288
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   289
static void string_set(char** out, const char* in)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   290
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   291
  size_t insize = strlen(in), i = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   292
  if(string_resize(out, insize)) for(i = 0; i < insize; i++) (*out)[i] = in[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   293
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   294
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   295
#endif /*LODEPNG_COMPILE_PNG*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   296
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   297
#ifdef LODEPNG_COMPILE_ZLIB
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   298
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   299
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   300
/* / Reading and writing single bits and bytes from/to stream for Deflate   / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   301
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   302
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   303
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   304
static void addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   305
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   306
  if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, 0); /*add a new byte at the end*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   307
  (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   308
  (*bitpointer)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   309
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   310
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   311
static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   312
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   313
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   314
  for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   315
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   316
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   317
static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   318
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   319
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   320
  for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   321
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   322
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   323
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   324
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   325
static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   326
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   327
  unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> ((*bitpointer) & 0x7)) & 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   328
  (*bitpointer)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   329
  return result;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   330
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   331
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   332
static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   333
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   334
  unsigned result = 0, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   335
  for(i = 0; i < nbits; i++) result += ((unsigned)readBitFromStream(bitpointer, bitstream)) << i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   336
  return result;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   337
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   338
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   339
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   340
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   341
/* / Deflate - Huffman                                                      / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   342
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   343
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   344
#define FIRST_LENGTH_CODE_INDEX 257
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   345
#define LAST_LENGTH_CODE_INDEX 285
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   346
#define NUM_DEFLATE_CODE_SYMBOLS 288 /*256 literals, the end code, some length codes, and 2 unused codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   347
#define NUM_DISTANCE_SYMBOLS 32 /*the distance codes have their own symbols, 30 used, 2 unused*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   348
#define NUM_CODE_LENGTH_CODES 19 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   349
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   350
static const unsigned LENGTHBASE[29] /*the base lengths represented by codes 257-285*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   351
  = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   352
static const unsigned LENGTHEXTRA[29] /*the extra bits used by codes 257-285 (added to base length)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   353
  = {0, 0, 0, 0, 0, 0, 0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,  4,  4,  4,   4,   5,   5,   5,   5,   0};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   354
static const unsigned DISTANCEBASE[30] /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   355
  = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   356
static const unsigned DISTANCEEXTRA[30] /*the extra bits of backwards distances (added to base)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   357
  = {0, 0, 0, 0, 1, 1, 2,  2,  3,  3,  4,  4,  5,  5,   6,   6,   7,   7,   8,   8,    9,    9,   10,   10,   11,   11,   12,    12,    13,    13};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   358
static const unsigned CLCL[NUM_CODE_LENGTH_CODES] /*the order in which "code length alphabet code lengths" are stored, out of this the huffman tree of the dynamic huffman tree lengths is generated*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   359
  = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   360
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   361
/* /////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   362
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   363
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   364
/*terminology used for the package-merge algorithm and the coin collector's problem*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   365
typedef struct Coin /*a coin can be multiple coins (when they're merged)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   366
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   367
  uivector symbols;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   368
  float weight; /*the sum of all weights in this coin*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   369
} Coin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   370
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   371
static void Coin_init(Coin* c)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   372
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   373
  uivector_init(&c->symbols);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   374
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   375
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   376
static void Coin_cleanup(void* c) /*void* so that this dtor can be given as function pointer to the vector resize function*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   377
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   378
  uivector_cleanup(&((Coin*)c)->symbols);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   379
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   380
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   381
static void Coin_copy(Coin* c1, const Coin* c2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   382
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   383
  c1->weight = c2->weight;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   384
  uivector_copy(&c1->symbols, &c2->symbols);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   385
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   386
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   387
static void addCoins(Coin* c1, const Coin* c2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   388
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   389
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   390
  for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   391
  c1->weight += c2->weight;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   392
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   393
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   394
static void Coin_sort(Coin* data, size_t amount) /*combsort*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   395
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   396
  size_t gap = amount;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   397
  unsigned char swapped = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   398
  while(gap > 1 || swapped)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   399
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   400
    size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   401
    gap = (gap * 10) / 13; /*shrink factor 1.3*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   402
    if(gap == 9 || gap == 10) gap = 11; /*combsort11*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   403
    if(gap < 1) gap = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   404
    swapped = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   405
    for(i = 0; i < amount - gap; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   406
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   407
      size_t j = i + gap;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   408
      if(data[j].weight < data[i].weight)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   409
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   410
        float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   411
        uivector_swap(&data[i].symbols, &data[j].symbols);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   412
        swapped = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   413
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   414
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   415
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   416
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   417
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   418
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   419
typedef struct HuffmanTree
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   420
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   421
  uivector tree2d;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   422
  uivector tree1d;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   423
  uivector lengths; /*the lengths of the codes of the 1d-tree*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   424
  unsigned maxbitlen; /*maximum number of bits a single code can get*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   425
  unsigned numcodes; /*number of symbols in the alphabet = number of codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   426
} HuffmanTree;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   427
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   428
/*function used for debug purposes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   429
/*#include <iostream>
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   430
static void HuffmanTree_draw(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   431
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   432
  std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   433
  for(size_t i = 0; i < tree->tree1d.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   434
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   435
    if(tree->lengths.data[i])
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   436
      std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   437
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   438
  std::cout << std::endl;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   439
}*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   440
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   441
static void HuffmanTree_init(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   442
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   443
  uivector_init(&tree->tree2d);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   444
  uivector_init(&tree->tree1d);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   445
  uivector_init(&tree->lengths);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   446
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   447
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   448
static void HuffmanTree_cleanup(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   449
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   450
  uivector_cleanup(&tree->tree2d);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   451
  uivector_cleanup(&tree->tree1d);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   452
  uivector_cleanup(&tree->lengths);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   453
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   454
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   455
/*the tree representation used by the decoder. return value is error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   456
static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   457
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   458
  unsigned nodefilled = 0; /*up to which node it is filled*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   459
  unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   460
  unsigned n, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   461
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   462
  if(!uivector_resize(&tree->tree2d, tree->numcodes * 2)) return 9901; /*if failed return not enough memory error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   463
  /*convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as many columns as codes - 1
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   464
  a good huffmann tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. Here, the internal nodes are stored (what their 0 and 1 option point to). There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   465
  for(n = 0;  n < tree->numcodes * 2; n++) tree->tree2d.data[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   466
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   467
  for(n = 0; n < tree->numcodes; n++) /*the codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   468
  for(i = 0; i < tree->lengths.data[n]; i++) /*the bits for this code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   469
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   470
    unsigned char bit = (unsigned char)((tree->tree1d.data[n] >> (tree->lengths.data[n] - i - 1)) & 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   471
    if(treepos > tree->numcodes - 2) return 55; /*error 55: oversubscribed; see description in header*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   472
    if(tree->tree2d.data[2 * treepos + bit] == 32767) /*not yet filled in*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   473
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   474
      if(i + 1 == tree->lengths.data[n]) /*last bit*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   475
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   476
        tree->tree2d.data[2 * treepos + bit] = n; /*put the current code in it*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   477
        treepos = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   478
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   479
      else /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   480
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   481
        nodefilled++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   482
        tree->tree2d.data[2 * treepos + bit] = nodefilled + tree->numcodes; /*addresses encoded with numcodes added to it*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   483
        treepos = nodefilled;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   484
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   485
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   486
    else treepos = tree->tree2d.data[2 * treepos + bit] - tree->numcodes;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   487
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   488
  for(n = 0;  n < tree->numcodes * 2; n++) if(tree->tree2d.data[n] == 32767) tree->tree2d.data[n] = 0; /*remove possible remaining 32767's*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   489
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   490
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   491
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   492
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   493
static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) /*given that numcodes, lengths and maxbitlen are already filled in correctly. return value is error.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   494
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   495
  uivector blcount;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   496
  uivector nextcode;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   497
  unsigned bits, n, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   498
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   499
  uivector_init(&blcount);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   500
  uivector_init(&nextcode);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   501
  if(!uivector_resize(&tree->tree1d, tree->numcodes)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   502
  || !uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   503
  || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   504
    error = 9902;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   505
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   506
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   507
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   508
    /*step 1: count number of instances of each code length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   509
    for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths.data[bits]]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   510
    /*step 2: generate the nextcode values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   511
    for(bits = 1; bits <= tree->maxbitlen; bits++) nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   512
    /*step 3: generate all the codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   513
    for(n = 0; n < tree->numcodes; n++) if(tree->lengths.data[n] != 0) tree->tree1d.data[n] = nextcode.data[tree->lengths.data[n]]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   514
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   515
   
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   516
  uivector_cleanup(&blcount);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   517
  uivector_cleanup(&nextcode);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   518
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   519
  if(!error) return HuffmanTree_make2DTree(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   520
  else return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   521
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   522
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   523
/*given the code lengths (as stored in the PNG file), generate the tree as defined by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   524
static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   525
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   526
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   527
  if(!uivector_resize(&tree->lengths, numcodes)) return 9903;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   528
  for(i = 0; i < numcodes; i++) tree->lengths.data[i] = bitlen[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   529
  tree->numcodes = (unsigned)numcodes; /*number of symbols*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   530
  tree->maxbitlen = maxbitlen;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   531
  return HuffmanTree_makeFromLengths2(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   532
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   533
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   534
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   535
static unsigned HuffmanTree_fillInCoins(vector* coins, const unsigned* frequencies, unsigned numcodes, size_t sum)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   536
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   537
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   538
  for(i = 0; i < numcodes; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   539
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   540
    Coin* coin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   541
    if(frequencies[i] == 0) continue; /*it's important to exclude symbols that aren't present*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   542
    if(!vector_resize(coins, coins->size + 1)) { vector_cleanup(coins); return 9904; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   543
    coin = (Coin*)(vector_get(coins, coins->size - 1));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   544
    Coin_init(coin);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   545
    coin->weight = frequencies[i] / (float)sum;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   546
    uivector_push_back(&coin->symbols, i);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   547
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   548
  if(coins->size) Coin_sort((Coin*)coins->data, coins->size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   549
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   550
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   551
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   552
static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   553
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   554
  unsigned i, j;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   555
  size_t sum = 0, numpresent = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   556
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   557
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   558
  vector prev_row; /*type Coin, the previous row of coins*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   559
  vector coins; /*type Coin, the coins of the currently calculated row*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   560
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   561
  tree->maxbitlen = maxbitlen;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   562
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   563
  for(i = 0; i < numcodes; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   564
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   565
    if(frequencies[i] > 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   566
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   567
      numpresent++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   568
      sum += frequencies[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   569
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   570
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   571
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   572
  if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   573
  tree->numcodes = (unsigned)numcodes; /*number of symbols*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   574
  uivector_resize(&tree->lengths, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   575
  if(!uivector_resizev(&tree->lengths, tree->numcodes, 0)) return 9905;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   576
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   577
  if(numpresent == 0) /*there are no symbols at all, in that case add one symbol of value 0 to the tree (see RFC 1951 section 3.2.7) */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   578
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   579
    tree->lengths.data[0] = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   580
    return HuffmanTree_makeFromLengths2(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   581
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   582
  else if(numpresent == 1) /*the package merge algorithm gives wrong results if there's only one symbol (theoretically 0 bits would then suffice, but we need a proper symbol for zlib)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   583
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   584
    for(i = 0; i < numcodes; i++) if(frequencies[i]) tree->lengths.data[i] = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   585
    return HuffmanTree_makeFromLengths2(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   586
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   587
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   588
  vector_init(&coins, sizeof(Coin));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   589
  vector_init(&prev_row, sizeof(Coin));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   590
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   591
  /*Package-Merge algorithm represented by coin collector's problem
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   592
  For every symbol, maxbitlen coins will be created*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   593
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   594
  /*first row, lowest denominator*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   595
  error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   596
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   597
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   598
    for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   599
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   600
      vector_swap(&coins, &prev_row); /*swap instead of copying*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   601
      if(!vector_resized(&coins, 0, Coin_cleanup)) { error = 9906; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   602
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   603
      for(i = 0; i + 1 < prev_row.size; i += 2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   604
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   605
        if(!vector_resize(&coins, coins.size + 1)) { error = 9907; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   606
        Coin_init((Coin*)vector_get(&coins, coins.size - 1));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   607
        Coin_copy((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   608
        addCoins((Coin*)vector_get(&coins, coins.size - 1), (Coin*)vector_get(&prev_row, i + 1)); /*merge the coins into packages*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   609
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   610
      if(j < maxbitlen)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   611
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   612
        error = HuffmanTree_fillInCoins(&coins, frequencies, tree->numcodes, sum);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   613
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   614
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   615
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   616
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   617
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   618
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   619
    /*keep the coins with lowest weight, so that they add up to the amount of symbols - 1*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   620
    vector_resized(&coins, numpresent - 1, Coin_cleanup);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   621
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   622
    /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   623
    for(i = 0; i < coins.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   624
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   625
      Coin* coin = (Coin*)vector_get(&coins, i);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   626
      for(j = 0; j < coin->symbols.size; j++) tree->lengths.data[coin->symbols.data[j]]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   627
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   628
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   629
    error = HuffmanTree_makeFromLengths2(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   630
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   631
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   632
  vector_cleanupd(&coins, Coin_cleanup);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   633
  vector_cleanupd(&prev_row, Coin_cleanup);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   634
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   635
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   636
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   637
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   638
static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { return tree->tree1d.data[index]; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   639
static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { return tree->lengths.data[index]; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   640
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   641
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   642
/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   643
static unsigned generateFixedTree(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   644
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   645
  unsigned i, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   646
  uivector bitlen;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   647
  uivector_init(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   648
  if(!uivector_resize(&bitlen, NUM_DEFLATE_CODE_SYMBOLS)) error = 9909;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   649
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   650
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   651
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   652
    /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   653
    for(i =   0; i <= 143; i++) bitlen.data[i] = 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   654
    for(i = 144; i <= 255; i++) bitlen.data[i] = 9;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   655
    for(i = 256; i <= 279; i++) bitlen.data[i] = 7;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   656
    for(i = 280; i <= 287; i++) bitlen.data[i] = 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   657
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   658
    error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DEFLATE_CODE_SYMBOLS, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   659
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   660
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   661
  uivector_cleanup(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   662
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   663
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   664
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   665
static unsigned generateDistanceTree(HuffmanTree* tree)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   666
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   667
  unsigned i, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   668
  uivector bitlen;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   669
  uivector_init(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   670
  if(!uivector_resize(&bitlen, NUM_DISTANCE_SYMBOLS)) error = 9910;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   671
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   672
  /*there are 32 distance codes, but 30-31 are unused*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   673
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   674
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   675
    for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen.data[i] = 5;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   676
    error = HuffmanTree_makeFromLengths(tree, bitlen.data, NUM_DISTANCE_SYMBOLS, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   677
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   678
  uivector_cleanup(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   679
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   680
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   681
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   682
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   683
/*Decodes a symbol from the tree
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   684
if decoded is true, then result contains the symbol, otherwise it contains something unspecified (because the symbol isn't fully decoded yet)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   685
bit is the bit that was just read from the stream
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   686
you have to decode a full symbol (let the decode function return true) before you can try to decode another one, otherwise the state isn't reset
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   687
return value is error.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   688
static unsigned HuffmanTree_decode(const HuffmanTree* tree, unsigned* decoded, unsigned* result, unsigned* treepos, unsigned char bit)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   689
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   690
  if((*treepos) >= tree->numcodes) return 11; /*error: it appeared outside the codetree*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   691
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   692
  (*result) = tree->tree2d.data[2 * (*treepos) + bit];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   693
  (*decoded) = ((*result) < tree->numcodes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   694
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   695
  if(*decoded) (*treepos) = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   696
  else (*treepos) = (*result) - tree->numcodes;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   697
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   698
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   699
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   700
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   701
static unsigned huffmanDecodeSymbol(unsigned int* error, const unsigned char* in, size_t* bp, const HuffmanTree* codetree, size_t inlength)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   702
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   703
  unsigned treepos = 0, decoded, ct;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   704
  for(;;)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   705
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   706
    unsigned char bit;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   707
    if(((*bp) & 0x07) == 0 && ((*bp) >> 3) > inlength) { *error = 10; return 0; } /*error: end of input memory reached without endcode*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   708
    bit = readBitFromStream(bp, in);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   709
    *error = HuffmanTree_decode(codetree, &decoded, &ct, &treepos, bit);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   710
    if(*error) return 0; /*stop, an error happened*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   711
    if(decoded) return ct;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   712
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   713
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   714
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   715
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   716
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   717
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   718
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   719
/* / Inflator                                                               / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   720
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   721
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   722
/*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   723
static void getTreeInflateFixed(HuffmanTree* tree, HuffmanTree* treeD)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   724
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   725
  /*error checking not done, this is fixed stuff, it works, it doesn't depend on the image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   726
  generateFixedTree(tree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   727
  generateDistanceTree(treeD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   728
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   729
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   730
/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   731
static unsigned getTreeInflateDynamic(HuffmanTree* codetree, HuffmanTree* codetreeD, HuffmanTree* codelengthcodetree,
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   732
                                      const unsigned char* in, size_t* bp, size_t inlength)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   733
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   734
  /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   735
  /*C-code note: use no "return" between ctor and dtor of an uivector!*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   736
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   737
  unsigned n, HLIT, HDIST, HCLEN, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   738
  uivector bitlen;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   739
  uivector bitlenD;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   740
  uivector codelengthcode;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   741
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   742
  if((*bp) >> 3 >= inlength - 2) { return 49; } /*the bit pointer is or will go past the memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   743
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   744
  HLIT =  readBitsFromStream(bp, in, 5) + 257; /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   745
  HDIST = readBitsFromStream(bp, in, 5) + 1; /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   746
  HCLEN = readBitsFromStream(bp, in, 4) + 4; /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   747
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   748
  /*read the code length codes out of 3 * (amount of code length codes) bits*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   749
  uivector_init(&codelengthcode);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   750
  if(!uivector_resize(&codelengthcode, NUM_CODE_LENGTH_CODES)) error = 9911;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   751
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   752
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   753
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   754
    for(i = 0; i < NUM_CODE_LENGTH_CODES; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   755
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   756
      if(i < HCLEN) codelengthcode.data[CLCL[i]] = readBitsFromStream(bp, in, 3);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   757
      else codelengthcode.data[CLCL[i]] = 0; /*if not, it must stay 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   758
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   759
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   760
    error = HuffmanTree_makeFromLengths(codelengthcodetree, codelengthcode.data, codelengthcode.size, 7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   761
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   762
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   763
  uivector_cleanup(&codelengthcode);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   764
  if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   765
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   766
  /*now we can use this tree to read the lengths for the tree that this function will return*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   767
  uivector_init(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   768
  uivector_resizev(&bitlen, NUM_DEFLATE_CODE_SYMBOLS, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   769
  uivector_init(&bitlenD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   770
  uivector_resizev(&bitlenD, NUM_DISTANCE_SYMBOLS, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   771
  i = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   772
  if(!bitlen.data || !bitlenD.data) error = 9912;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   773
  else while(i < HLIT + HDIST) /*i is the current symbol we're reading in the part that contains the code lengths of lit/len codes and dist codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   774
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   775
    unsigned code = huffmanDecodeSymbol(&error, in, bp, codelengthcodetree, inlength);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   776
    if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   777
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   778
    if(code <= 15) /*a length code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   779
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   780
      if(i < HLIT) bitlen.data[i] = code;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   781
      else bitlenD.data[i - HLIT] = code;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   782
      i++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   783
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   784
    else if(code == 16) /*repeat previous*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   785
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   786
      unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   787
      unsigned value; /*set value to the previous code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   788
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   789
      if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   790
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   791
      replength += readBitsFromStream(bp, in, 2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   792
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   793
      if((i - 1) < HLIT) value = bitlen.data[i - 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   794
      else value = bitlenD.data[i - HLIT - 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   795
      /*repeat this value in the next lengths*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   796
      for(n = 0; n < replength; n++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   797
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   798
        if(i >= HLIT + HDIST) { error = 13; break; } /*error: i is larger than the amount of codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   799
        if(i < HLIT) bitlen.data[i] = value;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   800
        else bitlenD.data[i - HLIT] = value;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   801
        i++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   802
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   803
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   804
    else if(code == 17) /*repeat "0" 3-10 times*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   805
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   806
      unsigned replength = 3; /*read in the bits that indicate repeat length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   807
      if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   808
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   809
      replength += readBitsFromStream(bp, in, 3);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   810
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   811
      /*repeat this value in the next lengths*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   812
      for(n = 0; n < replength; n++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   813
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   814
        if(i >= HLIT + HDIST) { error = 14; break; } /*error: i is larger than the amount of codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   815
        if(i < HLIT) bitlen.data[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   816
        else bitlenD.data[i - HLIT] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   817
        i++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   818
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   819
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   820
    else if(code == 18) /*repeat "0" 11-138 times*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   821
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   822
      unsigned replength = 11; /*read in the bits that indicate repeat length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   823
      if((*bp) >> 3 >= inlength) { error = 50; break; } /*error, bit pointer jumps past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   824
      replength += readBitsFromStream(bp, in, 7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   825
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   826
      /*repeat this value in the next lengths*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   827
      for(n = 0; n < replength; n++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   828
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   829
        if(i >= HLIT + HDIST) { error = 15; break; } /*error: i is larger than the amount of codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   830
        if(i < HLIT) bitlen.data[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   831
        else bitlenD.data[i - HLIT] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   832
        i++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   833
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   834
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   835
    else { error = 16; break; } /*error: somehow an unexisting code appeared. This can never happen.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   836
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   837
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   838
  if(!error && bitlen.data[256] == 0) { error = 64; } /*the length of the end code 256 must be larger than 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   839
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   840
  /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   841
  if(!error) error = HuffmanTree_makeFromLengths(codetree, &bitlen.data[0], bitlen.size, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   842
  if(!error) error = HuffmanTree_makeFromLengths(codetreeD, &bitlenD.data[0], bitlenD.size, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   843
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   844
  uivector_cleanup(&bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   845
  uivector_cleanup(&bitlenD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   846
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   847
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   848
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   849
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   850
/*inflate a block with dynamic of fixed Huffman tree*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   851
static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength, unsigned btype)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   852
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   853
  unsigned endreached = 0, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   854
  HuffmanTree codetree; /*287, the code tree for Huffman codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   855
  HuffmanTree codetreeD; /*31, the code tree for distance codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   856
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   857
  HuffmanTree_init(&codetree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   858
  HuffmanTree_init(&codetreeD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   859
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   860
  if(btype == 1) getTreeInflateFixed(&codetree, &codetreeD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   861
  else if(btype == 2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   862
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   863
    HuffmanTree codelengthcodetree; /*18, the code tree for code length codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   864
    HuffmanTree_init(&codelengthcodetree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   865
    error = getTreeInflateDynamic(&codetree, &codetreeD, &codelengthcodetree, in, bp, inlength);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   866
    HuffmanTree_cleanup(&codelengthcodetree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   867
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   868
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   869
  while(!endreached && !error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   870
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   871
    unsigned code = huffmanDecodeSymbol(&error, in, bp, &codetree, inlength);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   872
    if(error) break; /*some error happened in the above function*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   873
    if(code == 256) endreached = 1; /*end code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   874
    else if(code <= 255) /*literal symbol*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   875
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   876
      if((*pos) >= out->size) ucvector_resize(out, ((*pos) + 1) * 2); /*reserve more room at once*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   877
      if((*pos) >= out->size) { error = 9913; break; } /*not enough memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   878
      out->data[(*pos)] = (unsigned char)(code);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   879
      (*pos)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   880
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   881
    else if(code >= FIRST_LENGTH_CODE_INDEX && code <= LAST_LENGTH_CODE_INDEX) /*length code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   882
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   883
      /*part 1: get length base*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   884
      size_t length = LENGTHBASE[code - FIRST_LENGTH_CODE_INDEX];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   885
      unsigned codeD, distance, numextrabitsD;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   886
      size_t start, forward, backward, numextrabits;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   887
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   888
      /*part 2: get extra bits and add the value of that to length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   889
      numextrabits = LENGTHEXTRA[code - FIRST_LENGTH_CODE_INDEX];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   890
      if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   891
      length += readBitsFromStream(bp, in, numextrabits);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   892
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   893
      /*part 3: get distance code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   894
      codeD = huffmanDecodeSymbol(&error, in, bp, &codetreeD, inlength);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   895
      if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   896
      if(codeD > 29) { error = 18; break; } /*error: invalid distance code (30-31 are never used)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   897
      distance = DISTANCEBASE[codeD];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   898
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   899
      /*part 4: get extra bits from distance*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   900
      numextrabitsD = DISTANCEEXTRA[codeD];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   901
      if(((*bp) >> 3) >= inlength) { error = 51; break; } /*error, bit pointer will jump past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   902
      distance += readBitsFromStream(bp, in, numextrabitsD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   903
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   904
      /*part 5: fill in all the out[n] values based on the length and dist*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   905
      start = (*pos);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   906
      backward = start - distance;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   907
      if((*pos) + length >= out->size) ucvector_resize(out, ((*pos) + length) * 2); /*reserve more room at once*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   908
      if((*pos) + length >= out->size) { error = 9914; break; } /*not enough memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   909
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   910
      for(forward = 0; forward < length; forward++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   911
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   912
        out->data[(*pos)] = out->data[backward];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   913
        (*pos)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   914
        backward++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   915
        if(backward >= start) backward = start - distance;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   916
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   917
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   918
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   919
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   920
  HuffmanTree_cleanup(&codetree);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   921
  HuffmanTree_cleanup(&codetreeD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   922
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   923
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   924
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   925
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   926
static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   927
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   928
  /*go to first boundary of byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   929
  size_t p;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   930
  unsigned LEN, NLEN, n, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   931
  while(((*bp) & 0x7) != 0) (*bp)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   932
  p = (*bp) / 8; /*byte position*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   933
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   934
  /*read LEN (2 bytes) and NLEN (2 bytes)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   935
  if(p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   936
  LEN = in[p] + 256 * in[p + 1]; p += 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   937
  NLEN = in[p] + 256 * in[p + 1]; p += 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   938
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   939
  /*check if 16-bit NLEN is really the one's complement of LEN*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   940
  if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   941
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   942
  if((*pos) + LEN >= out->size) { if(!ucvector_resize(out, (*pos) + LEN)) return 9915; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   943
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   944
  /*read the literal data: LEN bytes are now stored in the out buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   945
  if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   946
  for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   947
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   948
  (*bp) = p * 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   949
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   950
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   951
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   952
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   953
/*inflate the deflated data (cfr. deflate spec); return value is the error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   954
unsigned LodeFlate_inflate(ucvector* out, const unsigned char* in, size_t insize, size_t inpos)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   955
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   956
  size_t bp = 0; /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   957
  unsigned BFINAL = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   958
  size_t pos = 0; /*byte position in the out buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   959
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   960
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   961
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   962
  while(!BFINAL)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   963
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   964
    unsigned BTYPE;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   965
    if((bp >> 3) >= insize) return 52; /*error, bit pointer will jump past memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   966
    BFINAL = readBitFromStream(&bp, &in[inpos]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   967
    BTYPE = 1 * readBitFromStream(&bp, &in[inpos]); BTYPE += 2 * readBitFromStream(&bp, &in[inpos]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   968
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   969
    if(BTYPE == 3) return 20; /*error: invalid BTYPE*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   970
    else if(BTYPE == 0) error = inflateNoCompression(out, &in[inpos], &bp, &pos, insize); /*no compression*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   971
    else error = inflateHuffmanBlock(out, &in[inpos], &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   972
    if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   973
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   974
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   975
  if(!ucvector_resize(out, pos)) error = 9916; /*Only now we know the true size of out, resize it to that*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   976
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   977
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   978
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   979
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   980
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   981
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   982
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   983
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   984
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   985
/* / Deflator                                                               / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   986
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   987
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   988
static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   989
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   990
/*bitlen is the size in bits of the code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   991
static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   992
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   993
  addBitsToStreamReversed(bp, compressed, code, bitlen);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   994
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   995
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   996
/*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   997
static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   998
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
   999
  /*linear search implementation*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1000
  /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1001
  return array_size - 1;*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1002
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1003
  /*binary search implementation (not that much faster) (precondition: array_size > 0)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1004
  size_t left  = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1005
  size_t right = array_size - 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1006
  while(left <= right)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1007
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1008
    size_t mid = (left + right) / 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1009
    if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1010
    else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1011
    else return mid - 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1012
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1013
  return array_size - 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1014
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1015
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1016
static void addLengthDistance(uivector* values, size_t length, size_t distance)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1017
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1018
  /*values in encoded vector are those used by deflate:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1019
  0-255: literal bytes
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1020
  256: end
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1021
  257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1022
  286-287: invalid*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1023
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1024
  unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1025
  unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1026
  unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1027
  unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1028
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1029
  uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1030
  uivector_push_back(values, extra_length);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1031
  uivector_push_back(values, dist_code);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1032
  uivector_push_back(values, extra_distance);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1033
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1034
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1035
#if 0
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1036
/*the "brute force" version of the encodeLZ7 algorithm, not used anymore, kept here for reference*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1037
static void encodeLZ77_brute(uivector* out, const unsigned char* in, size_t size, unsigned windowSize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1038
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1039
  size_t pos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1040
  /*using pointer instead of vector for input makes it faster when NOT using optimization when compiling; no influence if optimization is used*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1041
  for(pos = 0; pos < size; pos++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1042
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1043
    size_t length = 0, offset = 0; /*the length and offset found for the current position*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1044
    size_t max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1045
    size_t current_offset;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1046
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1047
    /**search for the longest string**/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1048
    for(current_offset = 1; current_offset < max_offset; current_offset++) /*search backwards through all possible distances (=offsets)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1049
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1050
      size_t backpos = pos - current_offset;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1051
      if(in[backpos] == in[pos])
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1052
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1053
        /*test the next characters*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1054
        size_t current_length = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1055
        size_t backtest = backpos + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1056
        size_t foretest = pos + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1057
        while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum supporte length by deflate is max length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1058
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1059
          if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1060
          current_length++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1061
          backtest++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1062
          foretest++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1063
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1064
        if(current_length > length)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1065
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1066
          length = current_length; /*the longest length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1067
          offset = current_offset; /*the offset that is related to this longest length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1068
          if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1069
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1070
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1071
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1072
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1073
    /**encode it as length/distance pair or literal value**/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1074
    if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1075
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1076
      uivector_push_back(out, in[pos]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1077
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1078
    else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1079
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1080
      addLengthDistance(out, length, offset);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1081
      pos += (length - 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1082
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1083
  } /*end of the loop through each character of input*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1084
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1085
#endif
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1086
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1087
static const unsigned HASH_NUM_VALUES = 65536;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1088
static const unsigned HASH_NUM_CHARACTERS = 6;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1089
static const unsigned HASH_SHIFT = 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1090
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1091
Good and fast values: HASH_NUM_VALUES=65536, HASH_NUM_CHARACTERS=6, HASH_SHIFT=2
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1092
making HASH_NUM_CHARACTERS larger (like 8), makes the file size larger but is a bit faster
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1093
making HASH_NUM_CHARACTERS smaller (like 3), makes the file size smaller but is slower
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1094
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1095
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1096
static unsigned getHash(const unsigned char* data, size_t size, size_t pos)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1097
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1098
  unsigned result = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1099
  size_t amount, i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1100
  if(pos >= size) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1101
  amount = HASH_NUM_CHARACTERS; if(pos + amount >= size) amount = size - pos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1102
  for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1103
  return result % HASH_NUM_VALUES;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1104
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1105
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1106
/*LZ77-encode the data using a hash table technique to let it encode faster. Return value is error code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1107
static unsigned encodeLZ77(uivector* out, const unsigned char* in, size_t size, unsigned windowSize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1108
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1109
  /**generate hash table**/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1110
  vector table; /*HASH_NUM_VALUES uivectors; this represents what would be an std::vector<std::vector<unsigned> > in C++*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1111
  uivector tablepos1, tablepos2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1112
  unsigned pos, i, error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1113
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1114
  vector_init(&table, sizeof(uivector));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1115
  if(!vector_resize(&table, HASH_NUM_VALUES)) return 9917;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1116
  for(i = 0; i < HASH_NUM_VALUES; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1117
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1118
    uivector* v = (uivector*)vector_get(&table, i);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1119
    uivector_init(v);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1120
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1121
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1122
  /*remember start and end positions in the tables to searching in*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1123
  uivector_init(&tablepos1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1124
  uivector_init(&tablepos2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1125
  if(!uivector_resizev(&tablepos1, HASH_NUM_VALUES, 0)) error = 9918;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1126
  if(!uivector_resizev(&tablepos2, HASH_NUM_VALUES, 0)) error = 9919;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1127
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1128
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1129
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1130
    for(pos = 0; pos < size; pos++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1131
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1132
      unsigned length = 0, offset = 0; /*the length and offset found for the current position*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1133
      unsigned max_offset = pos < windowSize ? pos : windowSize; /*how far back to test*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1134
      unsigned tablepos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1135
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1136
      /*/search for the longest string*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1137
      /*first find out where in the table to start (the first value that is in the range from "pos - max_offset" to "pos")*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1138
      unsigned hash = getHash(in, size, pos);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1139
      if(!uivector_push_back((uivector*)vector_get(&table, hash), pos))  { error = 9920; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1140
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1141
      while(((uivector*)vector_get(&table, hash))->data[tablepos1.data[hash]] < pos - max_offset) tablepos1.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos - max_offset*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1142
      while(((uivector*)vector_get(&table, hash))->data[tablepos2.data[hash]] < pos) tablepos2.data[hash]++; /*it now points to the first value in the table for which the index is larger than or equal to pos*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1143
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1144
      for(tablepos = tablepos2.data[hash] - 1; tablepos >= tablepos1.data[hash] && tablepos < tablepos2.data[hash]; tablepos--)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1145
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1146
        unsigned backpos = ((uivector*)vector_get(&table, hash))->data[tablepos];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1147
        unsigned current_offset = pos - backpos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1148
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1149
        /*test the next characters*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1150
        unsigned current_length = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1151
        unsigned backtest = backpos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1152
        unsigned foretest = pos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1153
        while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH) /*maximum supporte length by deflate is max length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1154
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1155
          if(backpos >= pos) backpos -= current_offset; /*continue as if we work on the decoded bytes after pos by jumping back before pos*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1156
          current_length++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1157
          backtest++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1158
          foretest++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1159
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1160
        if(current_length > length)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1161
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1162
          length = current_length; /*the longest length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1163
          offset = current_offset; /*the offset that is related to this longest length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1164
          if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break; /*you can jump out of this for loop once a length of max length is found (gives significant speed gain)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1165
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1166
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1167
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1168
      /**encode it as length/distance pair or literal value**/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1169
      if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1170
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1171
        if(!uivector_push_back(out, in[pos])) { error = 9921; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1172
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1173
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1174
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1175
        unsigned j;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1176
        addLengthDistance(out, length, offset);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1177
        for(j = 0; j < length - 1; j++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1178
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1179
          pos++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1180
          if(!uivector_push_back((uivector*)vector_get(&table, getHash(in, size, pos)), pos)) { error = 9922; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1181
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1182
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1183
    } /*end of the loop through each character of input*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1184
  } /*end of "if(!error)"*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1185
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1186
  /*cleanup*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1187
  for(i = 0; i < table.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1188
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1189
    uivector* v = (uivector*)vector_get(&table, i);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1190
    uivector_cleanup(v);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1191
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1192
  vector_cleanup(&table);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1193
  uivector_cleanup(&tablepos1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1194
  uivector_cleanup(&tablepos2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1195
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1196
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1197
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1198
/* /////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1199
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1200
static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1201
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1202
  /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1203
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1204
  size_t i, j, numdeflateblocks = datasize / 65536 + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1205
  unsigned datapos = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1206
  for(i = 0; i < numdeflateblocks; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1207
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1208
    unsigned BFINAL, BTYPE, LEN, NLEN;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1209
    unsigned char firstbyte;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1210
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1211
    BFINAL = (i == numdeflateblocks - 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1212
    BTYPE = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1213
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1214
    firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1215
    ucvector_push_back(out, firstbyte);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1216
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1217
    LEN = 65535;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1218
    if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1219
    NLEN = 65535 - LEN;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1220
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1221
    ucvector_push_back(out, (unsigned char)(LEN % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1222
    ucvector_push_back(out, (unsigned char)(LEN / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1223
    ucvector_push_back(out, (unsigned char)(NLEN % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1224
    ucvector_push_back(out, (unsigned char)(NLEN / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1225
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1226
    /*Decompressed data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1227
    for(j = 0; j < 65535 && datapos < datasize; j++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1228
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1229
      ucvector_push_back(out, data[datapos++]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1230
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1231
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1232
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1233
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1234
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1235
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1236
/*write the encoded data, using lit/len as well as distance codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1237
static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, const HuffmanTree* codes, const HuffmanTree* codesD)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1238
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1239
  size_t i = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1240
  for(i = 0; i < lz77_encoded->size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1241
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1242
    unsigned val = lz77_encoded->data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1243
    addHuffmanSymbol(bp, out, HuffmanTree_getCode(codes, val), HuffmanTree_getLength(codes, val));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1244
    if(val > 256) /*for a length code, 3 more things have to be added*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1245
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1246
      unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1247
      unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1248
      unsigned length_extra_bits = lz77_encoded->data[++i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1249
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1250
      unsigned distance_code = lz77_encoded->data[++i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1251
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1252
      unsigned distance_index = distance_code;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1253
      unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1254
      unsigned distance_extra_bits = lz77_encoded->data[++i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1255
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1256
      addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1257
      addHuffmanSymbol(bp, out, HuffmanTree_getCode(codesD, distance_code), HuffmanTree_getLength(codesD, distance_code));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1258
      addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1259
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1260
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1261
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1262
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1263
static unsigned deflateDynamic(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1264
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1265
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1266
  after the BFINAL and BTYPE, the dynamic block consists out of the following:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1267
  - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1268
  - (HCLEN+4)*3 bits code lengths of code length alphabet
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1269
  - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1270
  - HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1271
  - compressed data
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1272
  - 256 (end code)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1273
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1274
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1275
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1276
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1277
  uivector lz77_encoded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1278
  HuffmanTree codes; /*tree for literal values and length codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1279
  HuffmanTree codesD; /*tree for distance codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1280
  HuffmanTree codelengthcodes;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1281
  uivector frequencies;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1282
  uivector frequenciesD;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1283
  uivector amounts; /*the amounts in the "normal" order*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1284
  uivector lldl;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1285
  uivector lldll; /*lit/len & dist code lenghts*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1286
  uivector clcls;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1287
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1288
  unsigned BFINAL = 1; /*make only one block... the first and final one*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1289
  size_t numcodes, numcodesD, i, bp = 0; /*the bit pointer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1290
  unsigned HLIT, HDIST, HCLEN;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1291
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1292
  uivector_init(&lz77_encoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1293
  HuffmanTree_init(&codes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1294
  HuffmanTree_init(&codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1295
  HuffmanTree_init(&codelengthcodes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1296
  uivector_init(&frequencies);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1297
  uivector_init(&frequenciesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1298
  uivector_init(&amounts);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1299
  uivector_init(&lldl);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1300
  uivector_init(&lldll);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1301
  uivector_init(&clcls);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1302
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1303
  while(!error) /*the goto-avoiding while construct: break out to go to the cleanup phase, a break at the end makes sure the while is never repeated*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1304
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1305
    if(settings->useLZ77)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1306
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1307
      error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize); /*LZ77 encoded*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1308
      if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1309
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1310
    else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1311
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1312
      if(!uivector_resize(&lz77_encoded, datasize)) { error = 9923; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1313
      for(i = 0; i < datasize; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1314
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1315
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1316
    if(!uivector_resizev(&frequencies, 286, 0)) { error = 9924; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1317
    if(!uivector_resizev(&frequenciesD, 30, 0)) { error = 9925; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1318
    for(i = 0; i < lz77_encoded.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1319
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1320
      unsigned symbol = lz77_encoded.data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1321
      frequencies.data[symbol]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1322
      if(symbol > 256)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1323
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1324
        unsigned dist = lz77_encoded.data[i + 2];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1325
        frequenciesD.data[dist]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1326
        i += 3;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1327
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1328
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1329
    frequencies.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1330
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1331
    error = HuffmanTree_makeFromFrequencies(&codes, frequencies.data, frequencies.size, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1332
    if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1333
    error = HuffmanTree_makeFromFrequencies(&codesD, frequenciesD.data, frequenciesD.size, 15);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1334
    if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1335
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1336
    addBitToStream(&bp, out, BFINAL);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1337
    addBitToStream(&bp, out, 0); /*first bit of BTYPE "dynamic"*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1338
    addBitToStream(&bp, out, 1); /*second bit of BTYPE "dynamic"*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1339
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1340
    numcodes = codes.numcodes; if(numcodes > 286) numcodes = 286;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1341
    numcodesD = codesD.numcodes; if(numcodesD > 30) numcodesD = 30;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1342
    for(i = 0; i < numcodes; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codes, (unsigned)i));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1343
    for(i = 0; i < numcodesD; i++) uivector_push_back(&lldll, HuffmanTree_getLength(&codesD, (unsigned)i));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1344
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1345
    /*make lldl smaller by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1346
    for(i = 0; i < (unsigned)lldll.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1347
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1348
      unsigned j = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1349
      while(i + j + 1 < (unsigned)lldll.size && lldll.data[i + j + 1] == lldll.data[i]) j++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1350
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1351
      if(lldll.data[i] == 0 && j >= 2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1352
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1353
        j++; /*include the first zero*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1354
        if(j <= 10) { uivector_push_back(&lldl, 17); uivector_push_back(&lldl, j - 3); }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1355
        else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1356
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1357
          if(j > 138) j = 138;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1358
          uivector_push_back(&lldl, 18); uivector_push_back(&lldl, j - 11);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1359
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1360
        i += (j - 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1361
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1362
      else if(j >= 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1363
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1364
        size_t k;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1365
        unsigned num = j / 6, rest = j % 6;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1366
        uivector_push_back(&lldl, lldll.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1367
        for(k = 0; k < num; k++) { uivector_push_back(&lldl, 16); uivector_push_back(&lldl,    6 - 3); }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1368
        if(rest >= 3)            { uivector_push_back(&lldl, 16); uivector_push_back(&lldl, rest - 3); }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1369
        else j -= rest;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1370
        i += j;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1371
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1372
      else uivector_push_back(&lldl, lldll.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1373
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1374
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1375
    /*generate huffmantree for the length codes of lit/len and dist codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1376
    if(!uivector_resizev(&amounts, 19, 0)) { error = 9926; break; } /*16 possible lengths (0-15) and 3 repeat codes (16, 17 and 18)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1377
    for(i = 0; i < lldl.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1378
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1379
      amounts.data[lldl.data[i]]++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1380
      if(lldl.data[i] >= 16) i++; /*after a repeat code come the bits that specify the amount, those don't need to be in the amounts calculation*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1381
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1382
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1383
    error = HuffmanTree_makeFromFrequencies(&codelengthcodes, amounts.data, amounts.size, 7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1384
    if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1385
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1386
    if(!uivector_resize(&clcls, 19)) { error = 9927; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1387
    for(i = 0; i < 19; i++) clcls.data[i] = HuffmanTree_getLength(&codelengthcodes, CLCL[i]); /*lenghts of code length tree is in the order as specified by deflate*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1388
    while(clcls.data[clcls.size - 1] == 0 && clcls.size > 4)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1389
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1390
      if(!uivector_resize(&clcls, clcls.size - 1)) { error = 9928; break; } /*remove zeros at the end, but minimum size must be 4*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1391
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1392
    if(error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1393
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1394
    /*write the HLIT, HDIST and HCLEN values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1395
    HLIT = (unsigned)(numcodes - 257);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1396
    HDIST = (unsigned)(numcodesD - 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1397
    HCLEN = (unsigned)clcls.size - 4;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1398
    addBitsToStream(&bp, out, HLIT, 5);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1399
    addBitsToStream(&bp, out, HDIST, 5);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1400
    addBitsToStream(&bp, out, HCLEN, 4);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1401
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1402
    /*write the code lenghts of the code length alphabet*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1403
    for(i = 0; i < HCLEN + 4; i++) addBitsToStream(&bp, out, clcls.data[i], 3);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1404
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1405
    /*write the lenghts of the lit/len AND the dist alphabet*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1406
    for(i = 0; i < lldl.size; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1407
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1408
      addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codelengthcodes, lldl.data[i]), HuffmanTree_getLength(&codelengthcodes, lldl.data[i]));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1409
      /*extra bits of repeat codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1410
      if(lldl.data[i] == 16) addBitsToStream(&bp, out, lldl.data[++i], 2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1411
      else if(lldl.data[i] == 17) addBitsToStream(&bp, out, lldl.data[++i], 3);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1412
      else if(lldl.data[i] == 18) addBitsToStream(&bp, out, lldl.data[++i], 7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1413
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1414
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1415
    /*write the compressed data symbols*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1416
    writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1417
    if(HuffmanTree_getLength(&codes, 256) == 0) { error = 64; break; } /*the length of the end code 256 must be larger than 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1418
    addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*end code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1419
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1420
    break; /*end of error-while*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1421
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1422
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1423
  /*cleanup*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1424
  uivector_cleanup(&lz77_encoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1425
  HuffmanTree_cleanup(&codes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1426
  HuffmanTree_cleanup(&codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1427
  HuffmanTree_cleanup(&codelengthcodes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1428
  uivector_cleanup(&frequencies);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1429
  uivector_cleanup(&frequenciesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1430
  uivector_cleanup(&amounts);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1431
  uivector_cleanup(&lldl);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1432
  uivector_cleanup(&lldll);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1433
  uivector_cleanup(&clcls);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1434
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1435
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1436
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1437
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1438
static unsigned deflateFixed(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1439
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1440
  HuffmanTree codes; /*tree for literal values and length codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1441
  HuffmanTree codesD; /*tree for distance codes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1442
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1443
  unsigned BFINAL = 1; /*make only one block... the first and final one*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1444
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1445
  size_t i, bp = 0; /*the bit pointer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1446
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1447
  HuffmanTree_init(&codes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1448
  HuffmanTree_init(&codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1449
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1450
  generateFixedTree(&codes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1451
  generateDistanceTree(&codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1452
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1453
  addBitToStream(&bp, out, BFINAL);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1454
  addBitToStream(&bp, out, 1); /*first bit of BTYPE*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1455
  addBitToStream(&bp, out, 0); /*second bit of BTYPE*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1456
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1457
  if(settings->useLZ77) /*LZ77 encoded*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1458
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1459
    uivector lz77_encoded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1460
    uivector_init(&lz77_encoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1461
    error = encodeLZ77(&lz77_encoded, data, datasize, settings->windowSize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1462
    if(!error) writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1463
    uivector_cleanup(&lz77_encoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1464
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1465
  else /*no LZ77, but still will be Huffman compressed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1466
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1467
    for(i = 0; i < datasize; i++) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, data[i]), HuffmanTree_getLength(&codes, data[i]));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1468
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1469
  if(!error) addHuffmanSymbol(&bp, out, HuffmanTree_getCode(&codes, 256), HuffmanTree_getLength(&codes, 256)); /*"end" code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1470
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1471
  /*cleanup*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1472
  HuffmanTree_cleanup(&codes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1473
  HuffmanTree_cleanup(&codesD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1474
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1475
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1476
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1477
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1478
unsigned LodeFlate_deflate(ucvector* out, const unsigned char* data, size_t datasize, const LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1479
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1480
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1481
  if(settings->btype == 0) error = deflateNoCompression(out, data, datasize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1482
  else if(settings->btype == 1) error = deflateFixed(out, data, datasize, settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1483
  else if(settings->btype == 2) error = deflateDynamic(out, data, datasize, settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1484
  else error = 61;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1485
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1486
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1487
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1488
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1489
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1490
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1491
/* / Adler32                                                                  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1492
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1493
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1494
static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1495
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1496
   unsigned s1 = adler & 0xffff;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1497
   unsigned s2 = (adler >> 16) & 0xffff;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1498
   
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1499
  while(len > 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1500
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1501
    /*at least 5550 sums can be done before the sums overflow, saving us from a lot of module divisions*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1502
    unsigned amount = len > 5550 ? 5550 : len;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1503
    len -= amount;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1504
    while(amount > 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1505
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1506
      s1 = (s1 + *data++);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1507
      s2 = (s2 + s1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1508
      amount--;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1509
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1510
    s1 %= 65521;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1511
    s2 %= 65521;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1512
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1513
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1514
  return (s2 << 16) | s1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1515
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1516
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1517
/*Return the adler32 of the bytes data[0..len-1]*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1518
static unsigned adler32(const unsigned char* data, unsigned len)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1519
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1520
  return update_adler32(1L, data, len);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1521
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1522
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1523
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1524
/* / Reading and writing single bits and bytes from/to stream for Zlib      / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1525
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1526
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1527
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1528
void LodeZlib_add32bitInt(ucvector* buffer, unsigned value)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1529
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1530
  ucvector_push_back(buffer, (unsigned char)((value >> 24) & 0xff));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1531
  ucvector_push_back(buffer, (unsigned char)((value >> 16) & 0xff));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1532
  ucvector_push_back(buffer, (unsigned char)((value >>  8) & 0xff));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1533
  ucvector_push_back(buffer, (unsigned char)((value      ) & 0xff));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1534
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1535
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1536
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1537
unsigned LodeZlib_read32bitInt(const unsigned char* buffer)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1538
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1539
  return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1540
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1541
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1542
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1543
/* / Zlib                                                                   / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1544
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1545
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1546
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1547
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1548
unsigned LodeZlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DecompressSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1549
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1550
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1551
  unsigned CM, CINFO, FDICT;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1552
  ucvector outv;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1553
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1554
  if(insize < 2) { error = 53; return error; } /*error, size of zlib data too small*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1555
  /*read information from zlib header*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1556
  if((in[0] * 256 + in[1]) % 31 != 0) { error = 24; return error; } /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1557
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1558
  CM = in[0] & 15;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1559
  CINFO = (in[0] >> 4) & 15;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1560
  /*FCHECK = in[1] & 31; //FCHECK is already tested above*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1561
  FDICT = (in[1] >> 5) & 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1562
  /*FLEVEL = (in[1] >> 6) & 3; //not really important, all it does it to give a compiler warning about unused variable, we don't care what encoding setting the encoder used*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1563
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1564
  if(CM != 8 || CINFO > 7) { error = 25; return error; } /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1565
  if(FDICT != 0) { error = 26; return error; } /*error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1566
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1567
  ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1568
  error = LodeFlate_inflate(&outv, in, insize, 2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1569
  *out = outv.data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1570
  *outsize = outv.size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1571
  if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1572
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1573
  if(!settings->ignoreAdler32)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1574
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1575
    unsigned ADLER32 = LodeZlib_read32bitInt(&in[insize - 4]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1576
    unsigned checksum = adler32(outv.data, (unsigned)outv.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1577
    if(checksum != ADLER32) { error = 58; return error; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1578
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1579
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1580
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1581
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1582
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1583
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1584
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1585
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1586
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1587
unsigned LodeZlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1588
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1589
  /*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1590
  ucvector deflatedata, outv;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1591
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1592
  unsigned error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1593
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1594
  unsigned ADLER32;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1595
  /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1596
  unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1597
  unsigned FLEVEL = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1598
  unsigned FDICT = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1599
  unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1600
  unsigned FCHECK = 31 - CMFFLG % 31;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1601
  CMFFLG += FCHECK;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1602
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1603
  ucvector_init_buffer(&outv, *out, *outsize); /*ucvector-controlled version of the output buffer, for dynamic array*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1604
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1605
  ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1606
  ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1607
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1608
  ucvector_init(&deflatedata);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1609
  error = LodeFlate_deflate(&deflatedata, in, insize, settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1610
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1611
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1612
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1613
    ADLER32 = adler32(in, (unsigned)insize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1614
    for(i = 0; i < deflatedata.size; i++) ucvector_push_back(&outv, deflatedata.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1615
    ucvector_cleanup(&deflatedata);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1616
    LodeZlib_add32bitInt(&outv, ADLER32);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1617
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1618
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1619
  *out = outv.data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1620
  *outsize = outv.size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1621
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1622
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1623
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1624
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1625
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1626
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1627
#endif /*LODEPNG_COMPILE_ZLIB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1628
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1629
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1630
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1631
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1632
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1633
void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1634
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1635
  settings->btype = 2; /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1636
  settings->useLZ77 = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1637
  settings->windowSize = 2048; /*this is a good tradeoff between speed and compression ratio*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1638
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1639
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1640
const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings = {2, 1, 2048};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1641
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1642
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1643
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1644
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1645
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1646
void LodeZlib_DecompressSettings_init(LodeZlib_DecompressSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1647
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1648
  settings->ignoreAdler32 = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1649
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1650
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1651
const LodeZlib_DecompressSettings LodeZlib_defaultDecompressSettings = {0};
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1652
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1653
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1654
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1655
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1656
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1657
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1658
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1659
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1660
/* // End of Zlib related code, now comes the PNG related code that uses it// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1661
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1662
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1663
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1664
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1665
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1666
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1667
#ifdef LODEPNG_COMPILE_PNG
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1668
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1669
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1670
The two functions below (LodePNG_decompress and LodePNG_compress) directly call the
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1671
LodeZlib_decompress and LodeZlib_compress functions. The only purpose of the functions
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1672
below, is to provide the ability to let LodePNG use a different Zlib encoder by only
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1673
changing the two functions below, instead of changing it inside the vareous places
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1674
in the other LodePNG functions.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1675
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1676
*out must be NULL and *outsize must be 0 initially, and after the function is done,
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1677
*out must point to the decompressed data, *outsize must be the size of it, and must
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1678
be the size of the useful data in bytes, not the alloc size.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1679
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1680
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1681
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1682
static unsigned LodePNG_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DecompressSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1683
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1684
  return LodeZlib_decompress(out, outsize, in, insize, settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1685
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1686
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1687
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1688
static unsigned LodePNG_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodeZlib_DeflateSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1689
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1690
  return LodeZlib_compress(out, outsize, in, insize, settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1691
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1692
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1693
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1694
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1695
/* / CRC32                                                                  / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1696
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1697
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1698
static unsigned Crc32_crc_table_computed = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1699
static unsigned Crc32_crc_table[256];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1700
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1701
/*Make the table for a fast CRC.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1702
static void Crc32_make_crc_table(void)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1703
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1704
  unsigned c, k, n;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1705
  for(n = 0; n < 256; n++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1706
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1707
    c = n;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1708
    for(k = 0; k < 8; k++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1709
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1710
      if(c & 1) c = 0xedb88320L ^ (c >> 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1711
      else c = c >> 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1712
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1713
    Crc32_crc_table[n] = c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1714
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1715
  Crc32_crc_table_computed = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1716
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1717
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1718
/*Update a running CRC with the bytes buf[0..len-1]--the CRC should be 
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1719
initialized to all 1's, and the transmitted value is the 1's complement of the
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1720
final running CRC (see the crc() routine below).*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1721
static unsigned Crc32_update_crc(const unsigned char* buf, unsigned crc, size_t len)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1722
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1723
  unsigned c = crc;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1724
  size_t n;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1725
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1726
  if(!Crc32_crc_table_computed) Crc32_make_crc_table();
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1727
  for(n = 0; n < len; n++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1728
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1729
    c = Crc32_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1730
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1731
  return c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1732
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1733
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1734
/*Return the CRC of the bytes buf[0..len-1].*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1735
static unsigned Crc32_crc(const unsigned char* buf, size_t len)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1736
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1737
  return Crc32_update_crc(buf, 0xffffffffL, len) ^ 0xffffffffL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1738
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1739
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1740
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1741
/* / Reading and writing single bits and bytes from/to stream for LodePNG   / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1742
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1743
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1744
static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1745
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1746
  unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1747
  (*bitpointer)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1748
  return result;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1749
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1750
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1751
static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1752
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1753
  unsigned result = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1754
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1755
  for(i = nbits - 1; i < nbits; i--) result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1756
  return result;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1757
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1758
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1759
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1760
static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1761
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1762
  /*the current bit in bitstream must be 0 for this to work*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1763
  if(bit) bitstream[(*bitpointer) >> 3] |=  (bit << (7 - ((*bitpointer) & 0x7))); /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1764
  (*bitpointer)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1765
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1766
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1767
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1768
static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1769
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1770
  /*the current bit in bitstream may be 0 or 1 for this to work*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1771
  if(bit == 0) bitstream[(*bitpointer) >> 3] &=  (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1772
  else bitstream[(*bitpointer) >> 3] |=  (1 << (7 - ((*bitpointer) & 0x7)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1773
  (*bitpointer)++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1774
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1775
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1776
static unsigned LodePNG_read32bitInt(const unsigned char* buffer)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1777
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1778
  return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1779
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1780
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1781
static void LodePNG_set32bitInt(unsigned char* buffer, unsigned value) /*buffer must have at least 4 allocated bytes available*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1782
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1783
  buffer[0] = (unsigned char)((value >> 24) & 0xff);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1784
  buffer[1] = (unsigned char)((value >> 16) & 0xff);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1785
  buffer[2] = (unsigned char)((value >>  8) & 0xff);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1786
  buffer[3] = (unsigned char)((value      ) & 0xff);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1787
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1788
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1789
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1790
static void LodePNG_add32bitInt(ucvector* buffer, unsigned value)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1791
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1792
  ucvector_resize(buffer, buffer->size + 4);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1793
  LodePNG_set32bitInt(&buffer->data[buffer->size - 4], value);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1794
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1795
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1796
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1797
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1798
/* / PNG chunks                                                             / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1799
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1800
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1801
unsigned LodePNG_chunk_length(const unsigned char* chunk) /*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1802
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1803
  return LodePNG_read32bitInt(&chunk[0]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1804
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1805
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1806
void LodePNG_chunk_type(char type[5], const unsigned char* chunk) /*puts the 4-byte type in null terminated string*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1807
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1808
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1809
  for(i = 0; i < 4; i++) type[i] = chunk[4 + i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1810
  type[4] = 0; /*null termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1811
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1812
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1813
unsigned char LodePNG_chunk_type_equals(const unsigned char* chunk, const char* type) /*check if the type is the given type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1814
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1815
  if(strlen(type) != 4) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1816
  return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1817
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1818
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1819
/*properties of PNG chunks gotten from capitalization of chunk type name, as defined by the standard*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1820
unsigned char LodePNG_chunk_critical(const unsigned char* chunk) /*0: ancillary chunk, 1: it's one of the critical chunk types*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1821
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1822
  return((chunk[4] & 32) == 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1823
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1824
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1825
unsigned char LodePNG_chunk_private(const unsigned char* chunk) /*0: public, 1: private*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1826
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1827
  return((chunk[6] & 32) != 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1828
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1829
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1830
unsigned char LodePNG_chunk_safetocopy(const unsigned char* chunk) /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1831
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1832
  return((chunk[7] & 32) != 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1833
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1834
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1835
unsigned char* LodePNG_chunk_data(unsigned char* chunk) /*get pointer to the data of the chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1836
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1837
  return &chunk[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1838
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1839
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1840
const unsigned char* LodePNG_chunk_data_const(const unsigned char* chunk) /*get pointer to the data of the chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1841
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1842
  return &chunk[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1843
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1844
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1845
unsigned LodePNG_chunk_check_crc(const unsigned char* chunk) /*returns 0 if the crc is correct, error code if it's incorrect*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1846
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1847
  unsigned length = LodePNG_chunk_length(chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1848
  unsigned CRC = LodePNG_read32bitInt(&chunk[length + 8]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1849
  unsigned checksum = Crc32_crc(&chunk[4], length + 4); /*the CRC is taken of the data and the 4 chunk type letters, not the length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1850
  if(CRC != checksum) return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1851
  else return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1852
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1853
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1854
void LodePNG_chunk_generate_crc(unsigned char* chunk) /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1855
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1856
  unsigned length = LodePNG_chunk_length(chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1857
  unsigned CRC = Crc32_crc(&chunk[4], length + 4);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1858
  LodePNG_set32bitInt(chunk + 8 + length, CRC);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1859
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1860
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1861
unsigned char* LodePNG_chunk_next(unsigned char* chunk) /*don't use on IEND chunk, as there is no next chunk then*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1862
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1863
  unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1864
  return &chunk[total_chunk_length];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1865
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1866
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1867
const unsigned char* LodePNG_chunk_next_const(const unsigned char* chunk) /*don't use on IEND chunk, as there is no next chunk then*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1868
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1869
  unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1870
  return &chunk[total_chunk_length];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1871
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1872
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1873
unsigned LodePNG_append_chunk(unsigned char** out, size_t* outlength, const unsigned char* chunk) /*appends chunk that was already created, to the data. Returns error code.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1874
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1875
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1876
  unsigned total_chunk_length = LodePNG_chunk_length(chunk) + 12;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1877
  unsigned char *chunk_start, *new_buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1878
  size_t new_length = (*outlength) + total_chunk_length;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1879
  if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1880
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1881
  new_buffer = (unsigned char*)realloc(*out, new_length);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1882
  if(!new_buffer) return 9929;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1883
  (*out) = new_buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1884
  (*outlength) = new_length;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1885
  chunk_start = &(*out)[new_length - total_chunk_length];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1886
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1887
  for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1888
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1889
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1890
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1891
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1892
unsigned LodePNG_create_chunk(unsigned char** out, size_t* outlength, unsigned length, const char* type, const unsigned char* data) /*appends new chunk to out. Returns error code; may change memory address of out buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1893
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1894
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1895
  unsigned char *chunk, *new_buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1896
  size_t new_length = (*outlength) + length + 12;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1897
  if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1898
  new_buffer = (unsigned char*)realloc(*out, new_length);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1899
  if(!new_buffer) return 9930;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1900
  (*out) = new_buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1901
  (*outlength) = new_length;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1902
  chunk = &(*out)[(*outlength) - length - 12];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1903
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1904
  /*1: length*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1905
  LodePNG_set32bitInt(chunk, (unsigned)length);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1906
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1907
  /*2: chunk name (4 letters)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1908
  chunk[4] = type[0];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1909
  chunk[5] = type[1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1910
  chunk[6] = type[2];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1911
  chunk[7] = type[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1912
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1913
  /*3: the data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1914
  for(i = 0; i < length; i++) chunk[8 + i] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1915
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1916
  /*4: CRC (of the chunkname characters and the data)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1917
  LodePNG_chunk_generate_crc(chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1918
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1919
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1920
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1921
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1922
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1923
/* / Color types and such                                                   / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1924
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1925
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1926
/*return type is a LodePNG error code*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1927
static unsigned checkColorValidity(unsigned colorType, unsigned bd) /*bd = bitDepth*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1928
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1929
  switch(colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1930
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1931
    case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1932
    case 2: if(!(                                 bd == 8 || bd == 16)) return 37; break; /*RGB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1933
    case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8            )) return 37; break; /*palette*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1934
    case 4: if(!(                                 bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1935
    case 6: if(!(                                 bd == 8 || bd == 16)) return 37; break; /*RGBA*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1936
    default: return 31;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1937
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1938
  return 0; /*allowed color type / bits combination*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1939
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1940
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1941
static unsigned getNumColorChannels(unsigned colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1942
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1943
  switch(colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1944
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1945
    case 0: return 1; /*grey*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1946
    case 2: return 3; /*RGB*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1947
    case 3: return 1; /*palette*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1948
    case 4: return 2; /*grey + alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1949
    case 6: return 4; /*RGBA*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1950
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1951
  return 0; /*unexisting color type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1952
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1953
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1954
static unsigned getBpp(unsigned colorType, unsigned bitDepth)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1955
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1956
  return getNumColorChannels(colorType) * bitDepth; /*bits per pixel is amount of channels * bits per channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1957
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1958
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1959
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1960
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1961
void LodePNG_InfoColor_init(LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1962
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1963
  info->key_defined = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1964
  info->key_r = info->key_g = info->key_b = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1965
  info->colorType = 6;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1966
  info->bitDepth = 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1967
  info->palette = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1968
  info->palettesize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1969
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1970
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1971
void LodePNG_InfoColor_cleanup(LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1972
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1973
  LodePNG_InfoColor_clearPalette(info);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1974
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1975
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1976
void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1977
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1978
  if(info->palette) free(info->palette);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1979
  info->palettesize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1980
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1981
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1982
unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1983
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1984
  unsigned char* data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1985
  /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1986
  if(!(info->palettesize & (info->palettesize - 1))) /*if palettesize is 0 or a power of two*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1987
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1988
    /*allocated data must be at least 4* palettesize (for 4 color bytes)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1989
    size_t alloc_size = info->palettesize == 0 ? 4 : info->palettesize * 4 * 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1990
    data = (unsigned char*)realloc(info->palette, alloc_size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1991
    if(!data) return 9931;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1992
    else info->palette = data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1993
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1994
  info->palette[4 * info->palettesize + 0] = r;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1995
  info->palette[4 * info->palettesize + 1] = g;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1996
  info->palette[4 * info->palettesize + 2] = b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1997
  info->palette[4 * info->palettesize + 3] = a;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1998
  info->palettesize++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  1999
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2000
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2001
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2002
unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor* info) { return getBpp(info->colorType, info->bitDepth); } /*calculate bits per pixel out of colorType and bitDepth*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2003
unsigned LodePNG_InfoColor_getChannels(const LodePNG_InfoColor* info) { return getNumColorChannels(info->colorType); }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2004
unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor* info) { return info->colorType == 0 || info->colorType == 4; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2005
unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor* info) { return (info->colorType & 4) != 0; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2006
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2007
unsigned LodePNG_InfoColor_equal(const LodePNG_InfoColor* info1, const LodePNG_InfoColor* info2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2008
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2009
  return info1->colorType == info2->colorType
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2010
      && info1->bitDepth  == info2->bitDepth; /*palette and color key not compared*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2011
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2012
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2013
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2014
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2015
void LodePNG_UnknownChunks_init(LodePNG_UnknownChunks* chunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2016
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2017
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2018
  for(i = 0; i < 3; i++) chunks->data[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2019
  for(i = 0; i < 3; i++) chunks->datasize[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2020
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2021
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2022
void LodePNG_UnknownChunks_cleanup(LodePNG_UnknownChunks* chunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2023
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2024
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2025
  for(i = 0; i < 3; i++) free(chunks->data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2026
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2027
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2028
unsigned LodePNG_UnknownChunks_copy(LodePNG_UnknownChunks* dest, const LodePNG_UnknownChunks* src)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2029
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2030
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2031
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2032
  LodePNG_UnknownChunks_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2033
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2034
  for(i = 0; i < 3; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2035
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2036
    size_t j;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2037
    dest->datasize[i] = src->datasize[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2038
    dest->data[i] = (unsigned char*)malloc(src->datasize[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2039
    if(!dest->data[i] && dest->datasize[i]) return 9932;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2040
    for(j = 0; j < src->datasize[i]; j++) dest->data[i][j] = src->data[i][j];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2041
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2042
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2043
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2044
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2045
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2046
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2047
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2048
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2049
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2050
void LodePNG_Text_init(LodePNG_Text* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2051
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2052
  text->num = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2053
  text->keys = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2054
  text->strings = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2055
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2056
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2057
void LodePNG_Text_cleanup(LodePNG_Text* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2058
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2059
  LodePNG_Text_clear(text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2060
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2061
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2062
unsigned LodePNG_Text_copy(LodePNG_Text* dest, const LodePNG_Text* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2063
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2064
  size_t i = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2065
  dest->keys = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2066
  dest->strings = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2067
  dest->num = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2068
  for(i = 0; i < source->num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2069
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2070
    unsigned error = LodePNG_Text_add(dest, source->keys[i], source->strings[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2071
    if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2072
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2073
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2074
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2075
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2076
void LodePNG_Text_clear(LodePNG_Text* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2077
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2078
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2079
  for(i = 0; i < text->num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2080
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2081
    string_cleanup(&text->keys[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2082
    string_cleanup(&text->strings[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2083
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2084
  free(text->keys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2085
  free(text->strings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2086
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2087
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2088
unsigned LodePNG_Text_add(LodePNG_Text* text, const char* key, const char* str)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2089
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2090
  char** new_keys = (char**)(realloc(text->keys, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2091
  char** new_strings = (char**)(realloc(text->strings, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2092
  if(!new_keys || !new_strings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2093
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2094
    free(new_keys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2095
    free(new_strings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2096
    return 9933;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2097
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2098
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2099
  text->num++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2100
  text->keys = new_keys;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2101
  text->strings = new_strings;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2102
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2103
  string_init(&text->keys[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2104
  string_set(&text->keys[text->num - 1], key);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2105
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2106
  string_init(&text->strings[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2107
  string_set(&text->strings[text->num - 1], str);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2108
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2109
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2110
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2111
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2112
/******************************************************************************/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2113
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2114
void LodePNG_IText_init(LodePNG_IText* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2115
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2116
  text->num = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2117
  text->keys = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2118
  text->langtags = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2119
  text->transkeys = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2120
  text->strings = NULL;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2121
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2122
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2123
void LodePNG_IText_cleanup(LodePNG_IText* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2124
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2125
  LodePNG_IText_clear(text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2126
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2127
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2128
unsigned LodePNG_IText_copy(LodePNG_IText* dest, const LodePNG_IText* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2129
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2130
  size_t i = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2131
  dest->keys = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2132
  dest->langtags = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2133
  dest->transkeys = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2134
  dest->strings = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2135
  dest->num = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2136
  for(i = 0; i < source->num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2137
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2138
    unsigned error = LodePNG_IText_add(dest, source->keys[i], source->langtags[i], source->transkeys[i], source->strings[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2139
    if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2140
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2141
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2142
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2143
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2144
void LodePNG_IText_clear(LodePNG_IText* text)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2145
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2146
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2147
  for(i = 0; i < text->num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2148
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2149
    string_cleanup(&text->keys[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2150
    string_cleanup(&text->langtags[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2151
    string_cleanup(&text->transkeys[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2152
    string_cleanup(&text->strings[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2153
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2154
  free(text->keys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2155
  free(text->langtags);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2156
  free(text->transkeys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2157
  free(text->strings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2158
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2159
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2160
unsigned LodePNG_IText_add(LodePNG_IText* text, const char* key, const char* langtag, const char* transkey, const char* str)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2161
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2162
  char** new_keys = (char**)(realloc(text->keys, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2163
  char** new_langtags = (char**)(realloc(text->langtags, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2164
  char** new_transkeys = (char**)(realloc(text->transkeys, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2165
  char** new_strings = (char**)(realloc(text->strings, sizeof(char*) * (text->num + 1)));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2166
  if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2167
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2168
    free(new_keys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2169
    free(new_langtags);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2170
    free(new_transkeys);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2171
    free(new_strings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2172
    return 9934;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2173
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2174
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2175
  text->num++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2176
  text->keys = new_keys;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2177
  text->langtags = new_langtags;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2178
  text->transkeys = new_transkeys;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2179
  text->strings = new_strings;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2180
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2181
  string_init(&text->keys[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2182
  string_set(&text->keys[text->num - 1], key);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2183
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2184
  string_init(&text->langtags[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2185
  string_set(&text->langtags[text->num - 1], langtag);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2186
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2187
  string_init(&text->transkeys[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2188
  string_set(&text->transkeys[text->num - 1], transkey);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2189
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2190
  string_init(&text->strings[text->num - 1]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2191
  string_set(&text->strings[text->num - 1], str);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2192
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2193
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2194
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2195
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2196
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2197
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2198
void LodePNG_InfoPng_init(LodePNG_InfoPng* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2199
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2200
  info->width = info->height = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2201
  LodePNG_InfoColor_init(&info->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2202
  info->interlaceMethod = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2203
  info->compressionMethod = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2204
  info->filterMethod = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2205
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2206
  info->background_defined = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2207
  info->background_r = info->background_g = info->background_b = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2208
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2209
  LodePNG_Text_init(&info->text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2210
  LodePNG_IText_init(&info->itext);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2211
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2212
  info->time_defined = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2213
  info->phys_defined = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2214
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2215
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2216
  LodePNG_UnknownChunks_init(&info->unknown_chunks);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2217
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2218
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2219
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2220
void LodePNG_InfoPng_cleanup(LodePNG_InfoPng* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2221
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2222
  LodePNG_InfoColor_cleanup(&info->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2223
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2224
  LodePNG_Text_cleanup(&info->text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2225
  LodePNG_IText_cleanup(&info->itext);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2226
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2227
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2228
  LodePNG_UnknownChunks_cleanup(&info->unknown_chunks);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2229
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2230
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2231
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2232
unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng* dest, const LodePNG_InfoPng* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2233
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2234
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2235
  LodePNG_InfoPng_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2236
  *dest = *source;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2237
  LodePNG_InfoColor_init(&dest->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2238
  error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2239
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2240
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2241
  error = LodePNG_Text_copy(&dest->text, &source->text); if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2242
  error = LodePNG_IText_copy(&dest->itext, &source->itext); if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2243
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2244
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2245
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2246
  LodePNG_UnknownChunks_init(&dest->unknown_chunks);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2247
  error = LodePNG_UnknownChunks_copy(&dest->unknown_chunks, &source->unknown_chunks); if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2248
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2249
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2250
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2251
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2252
void LodePNG_InfoPng_swap(LodePNG_InfoPng* a, LodePNG_InfoPng* b)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2253
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2254
  LodePNG_InfoPng temp = *a;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2255
  *a = *b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2256
  *b = temp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2257
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2258
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2259
unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor* dest, const LodePNG_InfoColor* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2260
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2261
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2262
  LodePNG_InfoColor_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2263
  *dest = *source;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2264
  dest->palette = (unsigned char*)malloc(source->palettesize * 4);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2265
  if(!dest->palette && source->palettesize) return 9935;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2266
  for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2267
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2268
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2269
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2270
void LodePNG_InfoRaw_init(LodePNG_InfoRaw* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2271
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2272
  LodePNG_InfoColor_init(&info->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2273
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2274
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2275
void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2276
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2277
  LodePNG_InfoColor_cleanup(&info->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2278
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2279
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2280
unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw* dest, const LodePNG_InfoRaw* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2281
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2282
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2283
  LodePNG_InfoRaw_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2284
  *dest = *source;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2285
  LodePNG_InfoColor_init(&dest->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2286
  error = LodePNG_InfoColor_copy(&dest->color, &source->color); if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2287
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2288
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2289
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2290
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2291
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2292
/*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2293
converts from any color type to 24-bit or 32-bit (later maybe more supported). return value = LodePNG error code
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2294
the out buffer must have (w * h * bpp + 7) / 8 bytes, where bpp is the bits per pixel of the output color type (LodePNG_InfoColor_getBpp)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2295
for < 8 bpp images, there may _not_ be padding bits at the end of scanlines.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2296
*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2297
unsigned LodePNG_convert(unsigned char* out, const unsigned char* in, LodePNG_InfoColor* infoOut, LodePNG_InfoColor* infoIn, unsigned w, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2298
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2299
  const size_t numpixels = w * h; /*amount of pixels*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2300
  const unsigned OUT_BYTES = LodePNG_InfoColor_getBpp(infoOut) / 8; /*bytes per pixel in the output image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2301
  const unsigned OUT_ALPHA = LodePNG_InfoColor_isAlphaType(infoOut); /*use 8-bit alpha channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2302
  size_t i, c, bp = 0; /*bitpointer, used by less-than-8-bit color types*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2303
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2304
  /*cases where in and out already have the same format*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2305
  if(LodePNG_InfoColor_equal(infoIn, infoOut))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2306
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2307
    size_t i, size = (w * h * LodePNG_InfoColor_getBpp(infoIn) + 7) / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2308
    for(i = 0; i < size; i++) out[i] = in[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2309
    return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2310
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2311
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2312
  if((infoOut->colorType == 2 || infoOut->colorType == 6) && infoOut->bitDepth == 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2313
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2314
    if(infoIn->bitDepth == 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2315
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2316
      switch(infoIn->colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2317
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2318
        case 0: /*greyscale color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2319
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2320
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2321
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2322
            out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2323
            if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2324
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2325
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2326
        case 2: /*RGB color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2327
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2328
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2329
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2330
            for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[3 * i + c];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2331
            if(OUT_ALPHA && infoIn->key_defined == 1 && in[3 * i + 0] == infoIn->key_r && in[3 * i + 1] == infoIn->key_g && in[3 * i + 2] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2332
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2333
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2334
        case 3: /*indexed color (palette)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2335
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2336
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2337
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2338
            if(in[i] >= infoIn->palettesize) return 46;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2339
            for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * in[i] + c]; /*get rgb colors from the palette*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2340
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2341
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2342
        case 4: /*greyscale with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2343
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2344
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2345
            out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i + 0];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2346
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[2 * i + 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2347
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2348
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2349
        case 6: /*RGB with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2350
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2351
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2352
            for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[4 * i + c];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2353
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2354
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2355
        default: break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2356
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2357
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2358
    else if(infoIn->bitDepth == 16)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2359
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2360
      switch(infoIn->colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2361
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2362
        case 0: /*greyscale color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2363
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2364
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2365
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2366
            out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2367
            if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 3] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2368
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2369
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2370
        case 2: /*RGB color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2371
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2372
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2373
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2374
            for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[6 * i + 2 * c];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2375
            if(OUT_ALPHA && infoIn->key_defined && 256U * in[6 * i + 0] + in[6 * i + 1] == infoIn->key_r && 256U * in[6 * i + 2] + in[6 * i + 3] == infoIn->key_g && 256U * in[6 * i + 4] + in[6 * i + 5] == infoIn->key_b) out[OUT_BYTES * i + 3] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2376
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2377
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2378
        case 4: /*greyscale with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2379
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2380
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2381
            out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[4 * i]; /*most significant byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2382
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[4 * i + 2];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2383
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2384
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2385
        case 6: /*RGB with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2386
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2387
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2388
            for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[8 * i + 2 * c];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2389
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2390
          break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2391
        default: break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2392
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2393
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2394
    else /*infoIn->bitDepth is less than 8 bit per channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2395
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2396
      switch(infoIn->colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2397
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2398
        case 0: /*greyscale color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2399
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2400
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2401
            unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2402
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2403
            if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 3] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2404
            value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2405
            out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = (unsigned char)(value);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2406
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2407
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2408
        case 3: /*indexed color (palette)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2409
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2410
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2411
            unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2412
            if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2413
            if(value >= infoIn->palettesize) return 47;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2414
            for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->palette[4 * value + c]; /*get rgb colors from the palette*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2415
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2416
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2417
        default: break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2418
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2419
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2420
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2421
  else if(LodePNG_InfoColor_isGreyscaleType(infoOut) && infoOut->bitDepth == 8) /*conversion from greyscale to greyscale*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2422
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2423
    if(!LodePNG_InfoColor_isGreyscaleType(infoIn)) return 62;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2424
    if(infoIn->bitDepth == 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2425
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2426
      switch(infoIn->colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2427
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2428
        case 0: /*greyscale color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2429
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2430
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2431
            if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2432
            out[OUT_BYTES * i] = in[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2433
            if(OUT_ALPHA && infoIn->key_defined && in[i] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2434
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2435
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2436
        case 4: /*greyscale with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2437
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2438
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2439
            out[OUT_BYTES * i + 0] = in[2 * i + 0];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2440
            if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[2 * i + 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2441
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2442
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2443
        default: return 31;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2444
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2445
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2446
    else if(infoIn->bitDepth == 16)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2447
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2448
      switch(infoIn->colorType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2449
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2450
        case 0: /*greyscale color*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2451
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2452
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2453
            if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2454
            out[OUT_BYTES * i] = in[2 * i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2455
            if(OUT_ALPHA && infoIn->key_defined && 256U * in[i] + in[i + 1] == infoIn->key_r) out[OUT_BYTES * i + 1] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2456
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2457
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2458
        case 4: /*greyscale with alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2459
          for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2460
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2461
            out[OUT_BYTES * i] = in[4 * i]; /*most significant byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2462
            if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[4 * i + 2]; /*most significant byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2463
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2464
        break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2465
        default: return 31;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2466
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2467
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2468
    else /*infoIn->bitDepth is less than 8 bit per channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2469
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2470
      if(infoIn->colorType != 0) return 31; /*colorType 0 is the only greyscale type with < 8 bits per channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2471
      for(i = 0; i < numpixels; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2472
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2473
        unsigned value = readBitsFromReversedStream(&bp, in, infoIn->bitDepth);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2474
        if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2475
        if(OUT_ALPHA && infoIn->key_defined && value && ((1U << infoIn->bitDepth) - 1U) == infoIn->key_r && ((1U << infoIn->bitDepth) - 1U)) out[OUT_BYTES * i + 1] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2476
        value = (value * 255) / ((1 << infoIn->bitDepth) - 1); /*scale value from 0 to 255*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2477
        out[OUT_BYTES * i] = (unsigned char)(value);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2478
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2479
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2480
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2481
  else return 59;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2482
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2483
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2484
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2485
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2486
/*Paeth predicter, used by PNG filter type 4*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2487
static int paethPredictor(int a, int b, int c)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2488
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2489
  int p = a + b - c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2490
  int pa = p > a ? p - a : a - p;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2491
  int pb = p > b ? p - b : b - p;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2492
  int pc = p > c ? p - c : c - p;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2493
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2494
  if(pa <= pb && pa <= pc) return a;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2495
  else if(pb <= pc) return b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2496
  else return c;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2497
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2498
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2499
/*shared values used by multiple Adam7 related functions*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2500
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2501
static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2502
static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2503
static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2504
static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2505
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2506
static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2507
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2508
  /*the passstart values have 8 values: the 8th one actually indicates the byte after the end of the 7th (= last) pass*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2509
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2510
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2511
  /*calculate width and height in pixels of each pass*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2512
  for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2513
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2514
    passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2515
    passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2516
    if(passw[i] == 0) passh[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2517
    if(passh[i] == 0) passw[i] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2518
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2519
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2520
  filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2521
  for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2522
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2523
    filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2524
    padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); /*bits padded if needed to fill full byte at end of each scanline*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2525
    passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; /*only padded at end of reduced image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2526
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2527
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2528
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2529
#ifdef LODEPNG_COMPILE_DECODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2530
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2531
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2532
/* / PNG Decoder                                                            / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2533
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2534
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2535
/*read the information from the header and store it in the LodePNG_Info. return value is error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2536
void LodePNG_inspect(LodePNG_Decoder* decoder, const unsigned char* in, size_t inlength)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2537
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2538
  if(inlength == 0 || in == 0) { decoder->error = 48; return; } /*the given data is empty*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2539
  if(inlength < 29) { decoder->error = 27; return; } /*error: the data length is smaller than the length of the header*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2540
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2541
  /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2542
  LodePNG_InfoPng_cleanup(&decoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2543
  LodePNG_InfoPng_init(&decoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2544
  decoder->error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2545
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2546
  if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { decoder->error = 28; return; } /*error: the first 8 bytes are not the correct PNG signature*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2547
  if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { decoder->error = 29; return; } /*error: it doesn't start with a IHDR chunk!*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2548
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2549
  /*read the values given in the header*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2550
  decoder->infoPng.width = LodePNG_read32bitInt(&in[16]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2551
  decoder->infoPng.height = LodePNG_read32bitInt(&in[20]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2552
  decoder->infoPng.color.bitDepth = in[24];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2553
  decoder->infoPng.color.colorType = in[25];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2554
  decoder->infoPng.compressionMethod = in[26];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2555
  decoder->infoPng.filterMethod = in[27];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2556
  decoder->infoPng.interlaceMethod = in[28];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2557
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2558
  if(!decoder->settings.ignoreCrc)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2559
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2560
    unsigned CRC = LodePNG_read32bitInt(&in[29]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2561
    unsigned checksum = Crc32_crc(&in[12], 17);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2562
    if(CRC != checksum) { decoder->error = 57; return; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2563
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2564
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2565
  if(decoder->infoPng.compressionMethod != 0) { decoder->error = 32; return; } /*error: only compression method 0 is allowed in the specification*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2566
  if(decoder->infoPng.filterMethod != 0)      { decoder->error = 33; return; } /*error: only filter method 0 is allowed in the specification*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2567
  if(decoder->infoPng.interlaceMethod > 1)    { decoder->error = 34; return; } /*error: only interlace methods 0 and 1 exist in the specification*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2568
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2569
  decoder->error = checkColorValidity(decoder->infoPng.color.colorType, decoder->infoPng.color.bitDepth);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2570
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2571
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2572
static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, size_t bytewidth, unsigned char filterType, size_t length)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2573
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2574
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2575
  For PNG filter method 0
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2576
  unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, the filter works byte per byte (bytewidth = 1)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2577
  precon is the previous unfiltered scanline, recon the result, scanline the current one
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2578
  the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2579
  recon and scanline MAY be the same memory address! precon must be disjoint.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2580
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2581
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2582
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2583
  switch(filterType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2584
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2585
    case 0:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2586
      for(i = 0; i < length; i++) recon[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2587
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2588
    case 1:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2589
      for(i =         0; i < bytewidth; i++) recon[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2590
      for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + recon[i - bytewidth];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2591
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2592
    case 2: 
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2593
      if(precon) for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2594
      else       for(i = 0; i < length; i++) recon[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2595
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2596
    case 3:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2597
      if(precon)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2598
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2599
        for(i =         0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2600
        for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2601
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2602
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2603
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2604
        for(i =         0; i < bytewidth; i++) recon[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2605
        for(i = bytewidth; i <    length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2606
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2607
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2608
    case 4:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2609
      if(precon)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2610
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2611
        for(i =         0; i < bytewidth; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(0, precon[i], 0));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2612
        for(i = bytewidth; i <    length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2613
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2614
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2615
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2616
        for(i =         0; i < bytewidth; i++) recon[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2617
        for(i = bytewidth; i <    length; i++) recon[i] = (unsigned char)(scanline[i] + paethPredictor(recon[i - bytewidth], 0, 0));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2618
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2619
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2620
    default: return 36; /*error: unexisting filter type given*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2621
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2622
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2623
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2624
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2625
static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2626
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2627
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2628
  For PNG filter method 0
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2629
  this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 it's called 7 times)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2630
  out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2631
  w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2632
  in and out are allowed to be the same memory address!
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2633
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2634
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2635
  unsigned y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2636
  unsigned char* prevline = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2637
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2638
  size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2639
  size_t linebytes = (w * bpp + 7) / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2640
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2641
  for(y = 0; y < h; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2642
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2643
    size_t outindex = linebytes * y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2644
    size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2645
    unsigned char filterType = in[inindex];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2646
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2647
    unsigned error = unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2648
    if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2649
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2650
    prevline = &out[outindex];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2651
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2652
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2653
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2654
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2655
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2656
static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2657
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2658
  /*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2659
  out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation (because that's likely a little bit faster)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2660
  unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2661
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2662
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2663
  Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2664
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2665
  if(bpp >= 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2666
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2667
    for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2668
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2669
      unsigned x, y, b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2670
      size_t bytewidth = bpp / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2671
      for(y = 0; y < passh[i]; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2672
      for(x = 0; x < passw[i]; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2673
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2674
        size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2675
        size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2676
        for(b = 0; b < bytewidth; b++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2677
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2678
          out[pixeloutstart + b] = in[pixelinstart + b];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2679
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2680
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2681
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2682
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2683
  else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2684
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2685
    for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2686
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2687
      unsigned x, y, b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2688
      unsigned ilinebits = bpp * passw[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2689
      unsigned olinebits = bpp * w;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2690
      size_t obp, ibp; /*bit pointers (for out and in buffer)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2691
      for(y = 0; y < passh[i]; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2692
      for(x = 0; x < passw[i]; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2693
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2694
        ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2695
        obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2696
        for(b = 0; b < bpp; b++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2697
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2698
          unsigned char bit = readBitFromReversedStream(&ibp, in);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2699
          setBitOfReversedStream0(&obp, out, bit); /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2700
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2701
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2702
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2703
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2704
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2705
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2706
static void removePaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2707
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2708
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2709
  After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers for the Adam7 code, the color convert code and the output to the user.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2710
  in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2711
  also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2712
  only useful if (ilinebits - olinebits) is a value in the range 1..7
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2713
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2714
  unsigned y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2715
  size_t diff = ilinebits - olinebits;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2716
  size_t obp = 0, ibp = 0; /*bit pointers*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2717
  for(y = 0; y < h; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2718
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2719
    size_t x;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2720
    for(x = 0; x < olinebits; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2721
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2722
      unsigned char bit = readBitFromReversedStream(&ibp, in);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2723
      setBitOfReversedStream(&obp, out, bit);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2724
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2725
    ibp += diff;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2726
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2727
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2728
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2729
/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from the IDAT chunks*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2730
static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, const LodePNG_InfoPng* infoPng) /*return value is error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2731
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2732
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2733
  This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. Steps:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2734
  *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2735
  *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2736
  NOTE: the in buffer will be overwritten with intermediate data!
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2737
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2738
  unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2739
  unsigned w = infoPng->width;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2740
  unsigned h = infoPng->height;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2741
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2742
  if(bpp == 0) return 31; /*error: invalid colortype*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2743
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2744
  if(infoPng->interlaceMethod == 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2745
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2746
    if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2747
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2748
      error = unfilter(in, in, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2749
      if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2750
      removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2751
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2752
    else error = unfilter(out, in, w, h, bpp); /*we can immediatly filter into the out buffer, no other steps needed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2753
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2754
  else /*interlaceMethod is 1 (Adam7)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2755
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2756
    unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2757
    unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2758
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2759
    Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2760
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2761
    for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2762
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2763
      error = unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2764
      if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2765
      if(bpp < 8) /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, move bytes instead of bits or move not at all*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2766
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2767
        /*remove padding bits in scanlines; after this there still may be padding bits between the different reduced images: each reduced image still starts nicely at a byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2768
        removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7) / 8) * 8, passh[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2769
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2770
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2771
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2772
    Adam7_deinterlace(out, in, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2773
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2774
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2775
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2776
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2777
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2778
/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2779
static void decodeGeneric(LodePNG_Decoder* decoder, unsigned char** out, size_t* outsize, const unsigned char* in, size_t size)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2780
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2781
  unsigned char IEND = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2782
  const unsigned char* chunk;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2783
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2784
  ucvector idat; /*the data from idat chunks*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2785
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2786
  /*for unknown chunk order*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2787
  unsigned unknown = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2788
  unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2789
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2790
  /*provide some proper output values if error will happen*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2791
  *out = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2792
  *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2793
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2794
  if(size == 0 || in == 0) { decoder->error = 48; return; } /*the given data is empty*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2795
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2796
  LodePNG_inspect(decoder, in, size); /*reads header and resets other parameters in decoder->infoPng*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2797
  if(decoder->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2798
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2799
  ucvector_init(&idat);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2800
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2801
  chunk = &in[33]; /*first byte of the first chunk after the header*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2802
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2803
  while(!IEND) /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2804
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2805
    unsigned chunkLength;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2806
    const unsigned char* data; /*the data in the chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2807
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2808
    if((size_t)((chunk - in) + 12) > size || chunk < in) { decoder->error = 30; break; } /*error: size of the in buffer too small to contain next chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2809
    chunkLength = LodePNG_chunk_length(chunk); /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2810
    if(chunkLength > 2147483647) { decoder->error = 63; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2811
    if((size_t)((chunk - in) + chunkLength + 12) > size || (chunk + chunkLength + 12) < in) { decoder->error = 35; break; } /*error: size of the in buffer too small to contain next chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2812
    data = LodePNG_chunk_data_const(chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2813
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2814
    /*IDAT chunk, containing compressed image data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2815
    if(LodePNG_chunk_type_equals(chunk, "IDAT"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2816
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2817
      size_t oldsize = idat.size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2818
      if(!ucvector_resize(&idat, oldsize + chunkLength)) { decoder->error = 9936; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2819
      for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2820
      critical_pos = 3;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2821
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2822
    /*IEND chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2823
    else if(LodePNG_chunk_type_equals(chunk, "IEND"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2824
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2825
      IEND = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2826
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2827
    /*palette chunk (PLTE)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2828
    else if(LodePNG_chunk_type_equals(chunk, "PLTE"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2829
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2830
      unsigned pos = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2831
      if(decoder->infoPng.color.palette) free(decoder->infoPng.color.palette);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2832
      decoder->infoPng.color.palettesize = chunkLength / 3;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2833
      decoder->infoPng.color.palette = (unsigned char*)malloc(4 * decoder->infoPng.color.palettesize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2834
      if(!decoder->infoPng.color.palette && decoder->infoPng.color.palettesize) { decoder->error = 9937; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2835
      if(!decoder->infoPng.color.palette) decoder->infoPng.color.palettesize = 0; /*malloc failed...*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2836
      if(decoder->infoPng.color.palettesize > 256) { decoder->error = 38; break; } /*error: palette too big*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2837
      for(i = 0; i < decoder->infoPng.color.palettesize; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2838
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2839
        decoder->infoPng.color.palette[4 * i + 0] = data[pos++]; /*R*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2840
        decoder->infoPng.color.palette[4 * i + 1] = data[pos++]; /*G*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2841
        decoder->infoPng.color.palette[4 * i + 2] = data[pos++]; /*B*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2842
        decoder->infoPng.color.palette[4 * i + 3] = 255; /*alpha*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2843
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2844
      critical_pos = 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2845
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2846
    /*palette transparency chunk (tRNS)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2847
    else if(LodePNG_chunk_type_equals(chunk, "tRNS"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2848
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2849
      if(decoder->infoPng.color.colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2850
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2851
        if(chunkLength > decoder->infoPng.color.palettesize) { decoder->error = 39; break; } /*error: more alpha values given than there are palette entries*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2852
        for(i = 0; i < chunkLength; i++) decoder->infoPng.color.palette[4 * i + 3] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2853
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2854
      else if(decoder->infoPng.color.colorType == 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2855
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2856
        if(chunkLength != 2) { decoder->error = 40; break; } /*error: this chunk must be 2 bytes for greyscale image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2857
        decoder->infoPng.color.key_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2858
        decoder->infoPng.color.key_r = decoder->infoPng.color.key_g = decoder->infoPng.color.key_b = 256 * data[0] + data[1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2859
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2860
      else if(decoder->infoPng.color.colorType == 2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2861
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2862
        if(chunkLength != 6) { decoder->error = 41; break; } /*error: this chunk must be 6 bytes for RGB image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2863
        decoder->infoPng.color.key_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2864
        decoder->infoPng.color.key_r = 256 * data[0] + data[1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2865
        decoder->infoPng.color.key_g = 256 * data[2] + data[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2866
        decoder->infoPng.color.key_b = 256 * data[4] + data[5];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2867
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2868
      else { decoder->error = 42; break; } /*error: tRNS chunk not allowed for other color models*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2869
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2870
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2871
    /*background color chunk (bKGD)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2872
    else if(LodePNG_chunk_type_equals(chunk, "bKGD"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2873
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2874
      if(decoder->infoPng.color.colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2875
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2876
        if(chunkLength != 1) { decoder->error = 43; break; } /*error: this chunk must be 1 byte for indexed color image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2877
        decoder->infoPng.background_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2878
        decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_g = data[0];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2879
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2880
      else if(decoder->infoPng.color.colorType == 0 || decoder->infoPng.color.colorType == 4)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2881
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2882
        if(chunkLength != 2) { decoder->error = 44; break; } /*error: this chunk must be 2 bytes for greyscale image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2883
        decoder->infoPng.background_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2884
        decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_b = 256 * data[0] + data[1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2885
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2886
      else if(decoder->infoPng.color.colorType == 2 || decoder->infoPng.color.colorType == 6)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2887
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2888
        if(chunkLength != 6) { decoder->error = 45; break; } /*error: this chunk must be 6 bytes for greyscale image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2889
        decoder->infoPng.background_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2890
        decoder->infoPng.background_r = 256 * data[0] + data[1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2891
        decoder->infoPng.background_g = 256 * data[2] + data[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2892
        decoder->infoPng.background_b = 256 * data[4] + data[5];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2893
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2894
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2895
    /*text chunk (tEXt)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2896
    else if(LodePNG_chunk_type_equals(chunk, "tEXt"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2897
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2898
      if(decoder->settings.readTextChunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2899
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2900
        char *key = 0, *str = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2901
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2902
        while(!decoder->error) /*not really a while loop, only used to break on error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2903
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2904
          unsigned length, string2_begin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2905
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2906
          for(length = 0; length < chunkLength && data[length] != 0; length++) ;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2907
          if(length + 1 >= chunkLength) { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2908
          key = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2909
          if(!key) { decoder->error = 9938; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2910
          key[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2911
          for(i = 0; i < length; i++) key[i] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2912
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2913
          string2_begin = length + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2914
          if(string2_begin > chunkLength)  { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2915
          length = chunkLength - string2_begin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2916
          str = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2917
          if(!str) { decoder->error = 9939; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2918
          str[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2919
          for(i = 0; i < length; i++) str[i] = data[string2_begin + i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2920
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2921
          decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, str);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2922
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2923
          break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2924
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2925
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2926
        free(key);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2927
        free(str);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2928
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2929
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2930
    /*compressed text chunk (zTXt)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2931
    else if(LodePNG_chunk_type_equals(chunk, "zTXt"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2932
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2933
      if(decoder->settings.readTextChunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2934
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2935
        unsigned length, string2_begin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2936
        char *key = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2937
        ucvector decoded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2938
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2939
        ucvector_init(&decoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2940
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2941
        while(!decoder->error) /*not really a while loop, only used to break on error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2942
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2943
          for(length = 0; length < chunkLength && data[length] != 0; length++) ;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2944
          if(length + 2 >= chunkLength) { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2945
          key = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2946
          if(!key) { decoder->error = 9940; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2947
          key[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2948
          for(i = 0; i < length; i++) key[i] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2949
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2950
          if(data[length + 1] != 0) { decoder->error = 72; break; } /*the 0 byte indicating compression must be 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2951
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2952
          string2_begin = length + 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2953
          if(string2_begin > chunkLength)  { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2954
          length = chunkLength - string2_begin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2955
          decoder->error = LodePNG_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[string2_begin]), length, &decoder->settings.zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2956
          if(decoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2957
          ucvector_push_back(&decoded, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2958
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2959
          decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, (char*)decoded.data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2960
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2961
          break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2962
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2963
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2964
        free(key);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2965
        ucvector_cleanup(&decoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2966
        if(decoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2967
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2968
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2969
    /*international text chunk (iTXt)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2970
    else if(LodePNG_chunk_type_equals(chunk, "iTXt"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2971
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2972
      if(decoder->settings.readTextChunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2973
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2974
        unsigned length, begin, compressed;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2975
        char *key = 0, *langtag = 0, *transkey = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2976
        ucvector decoded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2977
        ucvector_init(&decoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2978
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2979
        while(!decoder->error) /*not really a while loop, only used to break on error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2980
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2981
          if(chunkLength < 5) { decoder->error = 76; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2982
          for(length = 0; length < chunkLength && data[length] != 0; length++) ;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2983
          if(length + 2 >= chunkLength) { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2984
          key = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2985
          if(!key) { decoder->error = 9941; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2986
          key[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2987
          for(i = 0; i < length; i++) key[i] = data[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2988
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2989
          compressed = data[length + 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2990
          if(data[length + 2] != 0) { decoder->error = 72; break; } /*the 0 byte indicating compression must be 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2991
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2992
          begin = length + 3;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2993
          length = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2994
          for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2995
          if(begin + length + 1 >= chunkLength) { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2996
          langtag = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2997
          if(!langtag) { decoder->error = 9942; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2998
          langtag[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  2999
          for(i = 0; i < length; i++) langtag[i] = data[begin + i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3000
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3001
          begin += length + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3002
          length = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3003
          for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3004
          if(begin + length + 1 >= chunkLength) { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3005
          transkey = (char*)malloc(length + 1);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3006
          if(!transkey) { decoder->error = 9943; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3007
          transkey[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3008
          for(i = 0; i < length; i++) transkey[i] = data[begin + i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3009
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3010
          begin += length + 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3011
          if(begin > chunkLength)  { decoder->error = 75; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3012
          length = chunkLength - begin;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3013
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3014
          if(compressed)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3015
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3016
            decoder->error = LodePNG_decompress(&decoded.data, &decoded.size, (unsigned char*)(&data[begin]), length, &decoder->settings.zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3017
            if(decoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3018
            ucvector_push_back(&decoded, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3019
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3020
          else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3021
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3022
            if(!ucvector_resize(&decoded, length + 1)) { decoder->error = 9944; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3023
            decoded.data[length] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3024
            for(i = 0; i < length; i++) decoded.data[i] = data[begin + i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3025
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3026
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3027
          decoder->error = LodePNG_IText_add(&decoder->infoPng.itext, key, langtag, transkey, (char*)decoded.data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3028
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3029
          break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3030
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3031
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3032
        free(key);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3033
        free(langtag);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3034
        free(transkey);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3035
        ucvector_cleanup(&decoded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3036
        if(decoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3037
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3038
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3039
    else if(LodePNG_chunk_type_equals(chunk, "tIME"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3040
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3041
      if(chunkLength != 7) { decoder->error = 73; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3042
      decoder->infoPng.time_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3043
      decoder->infoPng.time.year = 256 * data[0] + data[+ 1];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3044
      decoder->infoPng.time.month = data[2];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3045
      decoder->infoPng.time.day = data[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3046
      decoder->infoPng.time.hour = data[4];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3047
      decoder->infoPng.time.minute = data[5];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3048
      decoder->infoPng.time.second = data[6];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3049
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3050
    else if(LodePNG_chunk_type_equals(chunk, "pHYs"))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3051
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3052
      if(chunkLength != 9) { decoder->error = 74; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3053
      decoder->infoPng.phys_defined = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3054
      decoder->infoPng.phys_x = 16777216 * data[0] + 65536 * data[1] + 256 * data[2] + data[3];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3055
      decoder->infoPng.phys_y = 16777216 * data[4] + 65536 * data[5] + 256 * data[6] + data[7];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3056
      decoder->infoPng.phys_unit = data[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3057
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3058
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3059
    else /*it's not an implemented chunk type, so ignore it: skip over the data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3060
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3061
      if(LodePNG_chunk_critical(chunk)) { decoder->error = 69; break; } /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3062
      unknown = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3063
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3064
      if(decoder->settings.rememberUnknownChunks)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3065
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3066
        LodePNG_UnknownChunks* unknown = &decoder->infoPng.unknown_chunks;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3067
        decoder->error = LodePNG_append_chunk(&unknown->data[critical_pos - 1], &unknown->datasize[critical_pos - 1], chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3068
        if(decoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3069
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3070
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3071
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3072
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3073
    if(!decoder->settings.ignoreCrc && !unknown) /*check CRC if wanted, only on known chunk types*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3074
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3075
      if(LodePNG_chunk_check_crc(chunk)) { decoder->error = 57; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3076
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3077
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3078
    if(!IEND) chunk = LodePNG_chunk_next_const(chunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3079
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3080
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3081
  if(!decoder->error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3082
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3083
    ucvector scanlines;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3084
    ucvector_init(&scanlines);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3085
    if(!ucvector_resize(&scanlines, ((decoder->infoPng.width * (decoder->infoPng.height * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7)) / 8) + decoder->infoPng.height)) decoder->error = 9945; /*maximum final image length is already reserved in the vector's length - this is not really necessary*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3086
    if(!decoder->error) decoder->error = LodePNG_decompress(&scanlines.data, &scanlines.size, idat.data, idat.size, &decoder->settings.zlibsettings); /*decompress with the Zlib decompressor*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3087
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3088
    if(!decoder->error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3089
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3090
      ucvector outv;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3091
      ucvector_init(&outv);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3092
      if(!ucvector_resizev(&outv, (decoder->infoPng.height * decoder->infoPng.width * LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8, 0)) decoder->error = 9946;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3093
      if(!decoder->error) decoder->error = postProcessScanlines(outv.data, scanlines.data, &decoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3094
      *out = outv.data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3095
      *outsize = outv.size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3096
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3097
    ucvector_cleanup(&scanlines);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3098
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3099
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3100
  ucvector_cleanup(&idat);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3101
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3102
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3103
void LodePNG_decode(LodePNG_Decoder* decoder, unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3104
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3105
  *out = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3106
  *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3107
  decodeGeneric(decoder, out, outsize, in, insize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3108
  if(decoder->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3109
  if(!decoder->settings.color_convert || LodePNG_InfoColor_equal(&decoder->infoRaw.color, &decoder->infoPng.color))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3110
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3111
    /*same color type, no copying or converting of data needed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3112
    /*store the infoPng color settings on the infoRaw so that the infoRaw still reflects what colorType
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3113
    the raw image has to the end user*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3114
    if(!decoder->settings.color_convert)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3115
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3116
      decoder->error = LodePNG_InfoColor_copy(&decoder->infoRaw.color, &decoder->infoPng.color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3117
      if(decoder->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3118
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3119
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3120
  else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3121
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3122
    /*color conversion needed; sort of copy of the data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3123
    unsigned char* data = *out;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3124
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3125
    /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3126
    if(!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56; return; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3127
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3128
    *outsize = (decoder->infoPng.width * decoder->infoPng.height * LodePNG_InfoColor_getBpp(&decoder->infoRaw.color) + 7) / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3129
    *out = (unsigned char*)malloc(*outsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3130
    if(!(*out))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3131
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3132
      decoder->error = 9947;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3133
      *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3134
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3135
    else decoder->error = LodePNG_convert(*out, data, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3136
    free(data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3137
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3138
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3139
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3140
unsigned LodePNG_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3141
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3142
  unsigned error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3143
  size_t dummy_size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3144
  LodePNG_Decoder decoder;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3145
  LodePNG_Decoder_init(&decoder);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3146
  LodePNG_decode(&decoder, out, &dummy_size, in, insize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3147
  error = decoder.error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3148
  *w = decoder.infoPng.width;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3149
  *h = decoder.infoPng.height;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3150
  LodePNG_Decoder_cleanup(&decoder);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3151
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3152
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3153
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3154
#ifdef LODEPNG_COMPILE_DISK
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3155
unsigned LodePNG_decode32f(unsigned char** out, unsigned* w, unsigned* h, const char* filename)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3156
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3157
  unsigned char* buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3158
  size_t buffersize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3159
  unsigned error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3160
  error = LodePNG_loadFile(&buffer, &buffersize, filename);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3161
  if(!error) error = LodePNG_decode32(out, w, h, buffer, buffersize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3162
  free(buffer);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3163
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3164
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3165
#endif /*LODEPNG_COMPILE_DISK*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3166
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3167
void LodePNG_DecodeSettings_init(LodePNG_DecodeSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3168
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3169
  settings->color_convert = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3170
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3171
  settings->readTextChunks = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3172
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3173
  settings->ignoreCrc = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3174
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3175
  settings->rememberUnknownChunks = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3176
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3177
  LodeZlib_DecompressSettings_init(&settings->zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3178
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3179
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3180
void LodePNG_Decoder_init(LodePNG_Decoder* decoder)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3181
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3182
  LodePNG_DecodeSettings_init(&decoder->settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3183
  LodePNG_InfoRaw_init(&decoder->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3184
  LodePNG_InfoPng_init(&decoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3185
  decoder->error = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3186
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3187
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3188
void LodePNG_Decoder_cleanup(LodePNG_Decoder* decoder)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3189
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3190
  LodePNG_InfoRaw_cleanup(&decoder->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3191
  LodePNG_InfoPng_cleanup(&decoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3192
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3193
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3194
void LodePNG_Decoder_copy(LodePNG_Decoder* dest, const LodePNG_Decoder* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3195
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3196
  LodePNG_Decoder_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3197
  *dest = *source;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3198
  LodePNG_InfoRaw_init(&dest->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3199
  LodePNG_InfoPng_init(&dest->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3200
  dest->error = LodePNG_InfoRaw_copy(&dest->infoRaw, &source->infoRaw); if(dest->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3201
  dest->error = LodePNG_InfoPng_copy(&dest->infoPng, &source->infoPng); if(dest->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3202
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3203
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3204
#endif /*LODEPNG_COMPILE_DECODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3205
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3206
#ifdef LODEPNG_COMPILE_ENCODER
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3207
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3208
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3209
/* / PNG Encoder                                                            / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3210
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3211
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3212
/*chunkName must be string of 4 characters*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3213
static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3214
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3215
  unsigned error = LodePNG_create_chunk(&out->data, &out->size, (unsigned)length, chunkName, data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3216
  if(error) return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3217
  out->allocsize = out->size; /*fix the allocsize again*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3218
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3219
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3220
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3221
static void writeSignature(ucvector* out)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3222
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3223
  /*8 bytes PNG signature*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3224
  ucvector_push_back(out, 137);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3225
  ucvector_push_back(out, 80);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3226
  ucvector_push_back(out, 78);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3227
  ucvector_push_back(out, 71);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3228
  ucvector_push_back(out, 13);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3229
  ucvector_push_back(out, 10);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3230
  ucvector_push_back(out, 26);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3231
  ucvector_push_back(out, 10);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3232
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3233
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3234
static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, unsigned bitDepth, unsigned colorType, unsigned interlaceMethod)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3235
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3236
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3237
  ucvector header;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3238
  ucvector_init(&header);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3239
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3240
  LodePNG_add32bitInt(&header, w); /*width*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3241
  LodePNG_add32bitInt(&header, h); /*height*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3242
  ucvector_push_back(&header, (unsigned char)bitDepth); /*bit depth*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3243
  ucvector_push_back(&header, (unsigned char)colorType); /*color type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3244
  ucvector_push_back(&header, 0); /*compression method*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3245
  ucvector_push_back(&header, 0); /*filter method*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3246
  ucvector_push_back(&header, interlaceMethod); /*interlace method*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3247
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3248
  error = addChunk(out, "IHDR", header.data, header.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3249
  ucvector_cleanup(&header);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3250
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3251
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3252
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3253
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3254
static unsigned addChunk_PLTE(ucvector* out, const LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3255
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3256
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3257
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3258
  ucvector PLTE;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3259
  ucvector_init(&PLTE);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3260
  for(i = 0; i < info->palettesize * 4; i++) if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); /*add all channels except alpha channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3261
  error = addChunk(out, "PLTE", PLTE.data, PLTE.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3262
  ucvector_cleanup(&PLTE);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3263
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3264
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3265
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3266
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3267
static unsigned addChunk_tRNS(ucvector* out, const LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3268
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3269
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3270
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3271
  ucvector tRNS;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3272
  ucvector_init(&tRNS);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3273
  if(info->colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3274
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3275
    for(i = 0; i < info->palettesize; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); /*add only alpha channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3276
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3277
  else if(info->colorType == 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3278
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3279
    if(info->key_defined)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3280
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3281
      ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3282
      ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3283
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3284
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3285
  else if(info->colorType == 2)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3286
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3287
    if(info->key_defined)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3288
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3289
      ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3290
      ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3291
      ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3292
      ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3293
      ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3294
      ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3295
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3296
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3297
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3298
  error = addChunk(out, "tRNS", tRNS.data, tRNS.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3299
  ucvector_cleanup(&tRNS);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3300
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3301
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3302
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3303
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3304
static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, LodeZlib_DeflateSettings* zlibsettings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3305
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3306
  ucvector zlibdata;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3307
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3308
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3309
  /*compress with the Zlib compressor*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3310
  ucvector_init(&zlibdata);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3311
  error = LodePNG_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3312
  if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3313
  ucvector_cleanup(&zlibdata);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3314
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3315
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3316
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3317
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3318
static unsigned addChunk_IEND(ucvector* out)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3319
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3320
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3321
  error = addChunk(out, "IEND", 0, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3322
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3323
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3324
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3325
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3326
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3327
static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) /*add text chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3328
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3329
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3330
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3331
  ucvector text;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3332
  ucvector_init(&text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3333
  for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3334
  ucvector_push_back(&text, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3335
  for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3336
  error = addChunk(out, "tEXt", text.data, text.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3337
  ucvector_cleanup(&text);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3338
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3339
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3340
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3341
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3342
static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, LodeZlib_DeflateSettings* zlibsettings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3343
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3344
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3345
  ucvector data, compressed;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3346
  size_t i, textsize = strlen(textstring);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3347
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3348
  ucvector_init(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3349
  ucvector_init(&compressed);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3350
  for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3351
  ucvector_push_back(&data, 0); /* 0 termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3352
  ucvector_push_back(&data, 0); /*compression method: 0*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3353
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3354
  error = LodePNG_compress(&compressed.data, &compressed.size, (unsigned char*)textstring, textsize, zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3355
  if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3356
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3357
    for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3358
    error = addChunk(out, "zTXt", data.data, data.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3359
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3360
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3361
  ucvector_cleanup(&compressed);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3362
  ucvector_cleanup(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3363
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3364
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3365
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3366
static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, const char* transkey, const char* textstring, LodeZlib_DeflateSettings* zlibsettings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3367
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3368
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3369
  ucvector data, compressed_data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3370
  size_t i, textsize = strlen(textstring);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3371
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3372
  ucvector_init(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3373
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3374
  for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3375
  ucvector_push_back(&data, 0); /*null termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3376
  ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3377
  ucvector_push_back(&data, 0); /*compression method*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3378
  for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3379
  ucvector_push_back(&data, 0); /*null termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3380
  for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3381
  ucvector_push_back(&data, 0); /*null termination char*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3382
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3383
  if(compressed)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3384
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3385
    ucvector_init(&compressed_data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3386
    error = LodePNG_compress(&compressed_data.data, &compressed_data.size, (unsigned char*)textstring, textsize, zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3387
    if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3388
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3389
      for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3390
      for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3391
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3392
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3393
  else /*not compressed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3394
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3395
    for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3396
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3397
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3398
  if(!error) error = addChunk(out, "iTXt", data.data, data.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3399
  ucvector_cleanup(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3400
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3401
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3402
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3403
static unsigned addChunk_bKGD(ucvector* out, const LodePNG_InfoPng* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3404
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3405
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3406
  ucvector bKGD;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3407
  ucvector_init(&bKGD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3408
  if(info->color.colorType == 0 || info->color.colorType == 4)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3409
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3410
    ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3411
    ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3412
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3413
  else if(info->color.colorType == 2 || info->color.colorType == 6)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3414
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3415
    ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3416
    ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3417
    ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3418
    ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3419
    ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3420
    ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3421
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3422
  else if(info->color.colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3423
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3424
    ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3425
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3426
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3427
  error = addChunk(out, "bKGD", bKGD.data, bKGD.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3428
  ucvector_cleanup(&bKGD);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3429
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3430
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3431
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3432
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3433
static unsigned addChunk_tIME(ucvector* out, const LodePNG_Time* time)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3434
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3435
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3436
  unsigned char* data = (unsigned char*)malloc(7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3437
  if(!data) return 9948;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3438
  data[0] = (unsigned char)(time->year / 256);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3439
  data[1] = (unsigned char)(time->year % 256);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3440
  data[2] = time->month;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3441
  data[3] = time->day;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3442
  data[4] = time->hour;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3443
  data[5] = time->minute;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3444
  data[6] = time->second;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3445
  error = addChunk(out, "tIME", data, 7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3446
  free(data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3447
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3448
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3449
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3450
static unsigned addChunk_pHYs(ucvector* out, const LodePNG_InfoPng* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3451
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3452
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3453
  ucvector data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3454
  ucvector_init(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3455
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3456
  LodePNG_add32bitInt(&data, info->phys_x);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3457
  LodePNG_add32bitInt(&data, info->phys_y);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3458
  ucvector_push_back(&data, info->phys_unit);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3459
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3460
  error = addChunk(out, "pHYs", data.data, data.size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3461
  ucvector_cleanup(&data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3462
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3463
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3464
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3465
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3466
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3467
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3468
static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, size_t length, size_t bytewidth, unsigned char filterType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3469
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3470
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3471
  switch(filterType)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3472
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3473
    case 0:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3474
      if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3475
      else         for(i = 0; i < length; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3476
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3477
    case 1:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3478
      if(prevline)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3479
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3480
        for(i =         0; i < bytewidth; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3481
        for(i = bytewidth; i < length   ; i++) out[i] = scanline[i] - scanline[i - bytewidth];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3482
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3483
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3484
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3485
        for(i =         0; i < bytewidth; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3486
        for(i = bytewidth; i <    length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3487
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3488
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3489
    case 2:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3490
      if(prevline) for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3491
      else         for(i = 0; i < length; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3492
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3493
    case 3:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3494
      if(prevline)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3495
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3496
        for(i =         0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3497
        for(i = bytewidth; i <    length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3498
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3499
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3500
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3501
        for(i =         0; i < length; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3502
        for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3503
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3504
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3505
    case 4:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3506
      if(prevline)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3507
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3508
        for(i =         0; i < bytewidth; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(0, prevline[i], 0));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3509
        for(i = bytewidth; i <    length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3510
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3511
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3512
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3513
        for(i =         0; i < bytewidth; i++) out[i] = scanline[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3514
        for(i = bytewidth; i <    length; i++) out[i] = (unsigned char)(scanline[i] - paethPredictor(scanline[i - bytewidth], 0, 0));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3515
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3516
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3517
  default: return; /*unexisting filter type given*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3518
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3519
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3520
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3521
static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, const LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3522
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3523
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3524
  For PNG filter method 0
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3525
  out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3526
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3527
  There is a nice heuristic described here: http://www.cs.toronto.edu/~cosmin/pngtech/optipng.html. It says:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3528
   *  If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None).
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3529
   * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3530
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3531
  Here the above method is used mostly. Note though that it appears to be better to use the adaptive filtering on the plasma 8-bit palette example, but that image isn't the best reference for palette images in general.
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3532
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3533
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3534
  unsigned bpp = LodePNG_InfoColor_getBpp(info);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3535
  size_t linebytes = (w * bpp + 7) / 8; /*the width of a scanline in bytes, not including the filter type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3536
  size_t bytewidth = (bpp + 7) / 8; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3537
  const unsigned char* prevline = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3538
  unsigned x, y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3539
  unsigned heuristic;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3540
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3541
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3542
  if(bpp == 0) return 31; /*invalid color type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3543
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3544
  /*choose heuristic as described above*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3545
  if(info->colorType == 3 || info->bitDepth < 8) heuristic = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3546
  else heuristic = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3547
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3548
  if(heuristic == 0) /*None filtertype for everything*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3549
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3550
    for(y = 0; y < h; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3551
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3552
      size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3553
      size_t inindex = linebytes * y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3554
      const unsigned TYPE = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3555
      out[outindex] = TYPE; /*filter type byte*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3556
      filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, TYPE);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3557
      prevline = &in[inindex];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3558
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3559
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3560
  else if(heuristic == 1) /*adaptive filtering*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3561
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3562
    size_t sum[5];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3563
    ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3564
    size_t smallest = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3565
    unsigned type, bestType = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3566
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3567
    for(type = 0; type < 5; type++) ucvector_init(&attempt[type]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3568
    for(type = 0; type < 5; type++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3569
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3570
      if(!ucvector_resize(&attempt[type], linebytes)) { error = 9949; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3571
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3572
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3573
    if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3574
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3575
      for(y = 0; y < h; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3576
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3577
        /*try the 5 filter types*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3578
        for(type = 0; type < 5; type++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3579
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3580
          filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3581
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3582
          /*calculate the sum of the result*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3583
          sum[type] = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3584
          for(x = 0; x < attempt[type].size; x+=3) sum[type] += attempt[type].data[x]; /*note that not all pixels are checked to speed this up while still having probably the best choice*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3585
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3586
          /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3587
          if(type == 0 || sum[type] < smallest)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3588
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3589
            bestType = type;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3590
            smallest = sum[type];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3591
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3592
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3593
        
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3594
        prevline = &in[y * linebytes];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3595
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3596
        /*now fill the out values*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3597
        out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3598
        for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3599
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3600
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3601
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3602
    for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3603
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3604
  #if 0 /*deflate the scanline with a fixed tree after every filter attempt to see which one deflates best. This is slow, and _does not work as expected_: the heuristic gives smaller result!*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3605
  else if(heuristic == 2) /*adaptive filtering by using deflate*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3606
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3607
    size_t size[5];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3608
    ucvector attempt[5]; /*five filtering attempts, one for each filter type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3609
    size_t smallest;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3610
    unsigned type = 0, bestType = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3611
    unsigned char* dummy;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3612
    LodeZlib_DeflateSettings deflatesettings = LodeZlib_defaultDeflateSettings;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3613
    deflatesettings.btype = 1; /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3614
    for(type = 0; type < 5; type++) { ucvector_init(&attempt[type]); ucvector_resize(&attempt[type], linebytes); }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3615
    for(y = 0; y < h; y++) /*try the 5 filter types*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3616
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3617
      for(type = 0; type < 5; type++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3618
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3619
        filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3620
        size[type] = 0; dummy = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3621
        LodePNG_compress(&dummy, &size[type], attempt[type].data, attempt[type].size, &deflatesettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3622
        free(dummy);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3623
        /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3624
        if(type == 0 || size[type] < smallest) { bestType = type; smallest = size[type]; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3625
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3626
      prevline = &in[y * linebytes];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3627
      out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3628
      for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3629
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3630
    for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3631
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3632
  #endif
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3633
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3634
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3635
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3636
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3637
static void addPaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3638
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3639
  /*The opposite of the removePaddingBits function
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3640
  olinebits must be >= ilinebits*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3641
  unsigned y;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3642
  size_t diff = olinebits - ilinebits;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3643
  size_t obp = 0, ibp = 0; /*bit pointers*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3644
  for(y = 0; y < h; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3645
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3646
    size_t x;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3647
    for(x = 0; x < ilinebits; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3648
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3649
      unsigned char bit = readBitFromReversedStream(&ibp, in);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3650
      setBitOfReversedStream(&obp, out, bit);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3651
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3652
    /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3653
    for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3654
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3655
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3656
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3657
static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3658
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3659
  /*Note: this function works on image buffers WITHOUT padding bits at end of scanlines with non-multiple-of-8 bit amounts, only between reduced images is padding*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3660
  unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3661
  unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3662
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3663
  Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3664
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3665
  if(bpp >= 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3666
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3667
    for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3668
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3669
      unsigned x, y, b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3670
      size_t bytewidth = bpp / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3671
      for(y = 0; y < passh[i]; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3672
      for(x = 0; x < passw[i]; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3673
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3674
        size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3675
        size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3676
        for(b = 0; b < bytewidth; b++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3677
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3678
          out[pixeloutstart + b] = in[pixelinstart + b];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3679
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3680
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3681
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3682
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3683
  else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3684
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3685
    for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3686
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3687
      unsigned x, y, b;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3688
      unsigned ilinebits = bpp * passw[i];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3689
      unsigned olinebits = bpp * w;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3690
      size_t obp, ibp; /*bit pointers (for out and in buffer)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3691
      for(y = 0; y < passh[i]; y++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3692
      for(x = 0; x < passw[i]; x++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3693
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3694
        ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3695
        obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3696
        for(b = 0; b < bpp; b++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3697
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3698
          unsigned char bit = readBitFromReversedStream(&ibp, in);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3699
          setBitOfReversedStream(&obp, out, bit);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3700
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3701
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3702
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3703
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3704
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3705
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3706
/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3707
static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, const LodePNG_InfoPng* infoPng) /*return value is error*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3708
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3709
  /*
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3710
  This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps:
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3711
  *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3712
  *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3713
  */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3714
  unsigned bpp = LodePNG_InfoColor_getBpp(&infoPng->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3715
  unsigned w = infoPng->width;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3716
  unsigned h = infoPng->height;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3717
  unsigned error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3718
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3719
  if(infoPng->interlaceMethod == 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3720
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3721
    *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3722
    *out = (unsigned char*)malloc(*outsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3723
    if(!(*out) && (*outsize)) error = 9950;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3724
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3725
    if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3726
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3727
      if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) /*non multiple of 8 bits per scanline, padding bits needed per scanline*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3728
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3729
        ucvector padded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3730
        ucvector_init(&padded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3731
        if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9951;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3732
        if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3733
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3734
          addPaddingBits(padded.data, in, ((w * bpp + 7) / 8) * 8, w * bpp, h);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3735
          error = filter(*out, padded.data, w, h, &infoPng->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3736
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3737
        ucvector_cleanup(&padded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3738
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3739
      else error = filter(*out, in, w, h, &infoPng->color); /*we can immediatly filter into the out buffer, no other steps needed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3740
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3741
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3742
  else /*interlaceMethod is 1 (Adam7)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3743
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3744
    unsigned char* adam7 = (unsigned char*)malloc((h * w * bpp + 7) / 8);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3745
    if(!adam7 && ((h * w * bpp + 7) / 8)) error = 9952; /*malloc failed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3746
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3747
    while(!error) /*not a real while loop, used to break out to cleanup to avoid a goto*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3748
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3749
      unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3750
      unsigned i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3751
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3752
      Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3753
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3754
      *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3755
      *out = (unsigned char*)malloc(*outsize);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3756
      if(!(*out) && (*outsize)) { error = 9953; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3757
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3758
      Adam7_interlace(adam7, in, w, h, bpp);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3759
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3760
      for(i = 0; i < 7; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3761
      {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3762
        if(bpp < 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3763
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3764
          ucvector padded;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3765
          ucvector_init(&padded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3766
          if(!ucvector_resize(&padded, h * ((w * bpp + 7) / 8))) error = 9954;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3767
          if(!error)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3768
          {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3769
            addPaddingBits(&padded.data[padded_passstart[i]], &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3770
            error = filter(&(*out)[filter_passstart[i]], &padded.data[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3771
          }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3772
          
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3773
          ucvector_cleanup(&padded);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3774
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3775
        else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3776
        {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3777
          error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &infoPng->color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3778
        }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3779
      }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3780
      
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3781
      break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3782
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3783
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3784
    free(adam7);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3785
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3786
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3787
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3788
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3789
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3790
/*palette must have 4 * palettesize bytes allocated*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3791
static unsigned isPaletteFullyOpaque(const unsigned char* palette, size_t palettesize) /*palette given in format RGBARGBARGBARGBA...*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3792
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3793
  size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3794
  for(i = 0; i < palettesize; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3795
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3796
    if(palette[4 * i + 3] != 255) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3797
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3798
  return 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3799
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3800
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3801
/*this function checks if the input image given by the user has no transparent pixels*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3802
static unsigned isFullyOpaque(const unsigned char* image, unsigned w, unsigned h, const LodePNG_InfoColor* info)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3803
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3804
  /*TODO: When the user specified a color key for the input image, then this function must also check for pixels that are the same as the color key and treat those as transparent.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3805
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3806
  unsigned i, numpixels = w * h;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3807
  if(info->colorType == 6)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3808
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3809
    if(info->bitDepth == 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3810
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3811
      for(i = 0; i < numpixels; i++) if(image[i * 4 + 3] != 255) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3812
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3813
    else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3814
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3815
      for(i = 0; i < numpixels; i++) if(image[i * 8 + 6] != 255 || image[i * 8 + 7] != 255) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3816
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3817
    return 1; /*no single pixel with alpha channel other than 255 found*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3818
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3819
  else if(info->colorType == 4)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3820
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3821
    if(info->bitDepth == 8)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3822
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3823
      for(i = 0; i < numpixels; i++) if(image[i * 2 + 1] != 255) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3824
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3825
    else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3826
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3827
      for(i = 0; i < numpixels; i++) if(image[i * 4 + 2] != 255 || image[i * 4 + 3] != 255) return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3828
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3829
    return 1; /*no single pixel with alpha channel other than 255 found*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3830
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3831
  else if(info->colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3832
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3833
    /*when there's a palette, we could check every pixel for translucency, but much quicker is to just check the palette*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3834
    return(isPaletteFullyOpaque(info->palette, info->palettesize));
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3835
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3836
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3837
  return 0; /*color type that isn't supported by this function yet, so assume there is transparency to be safe*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3838
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3839
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3840
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3841
static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3842
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3843
  unsigned char* inchunk = data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3844
  while((size_t)(inchunk - data) < datasize)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3845
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3846
    unsigned error = LodePNG_append_chunk(&out->data, &out->size, inchunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3847
    if(error) return error; /*error: not enough memory*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3848
    out->allocsize = out->size; /*fix the allocsize again*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3849
    inchunk = LodePNG_chunk_next(inchunk);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3850
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3851
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3852
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3853
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3854
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3855
void LodePNG_encode(LodePNG_Encoder* encoder, unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3856
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3857
  LodePNG_InfoPng info;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3858
  ucvector outv;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3859
  unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3860
  size_t datasize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3861
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3862
  /*provide some proper output values if error will happen*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3863
  *out = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3864
  *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3865
  encoder->error = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3866
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3867
  info = encoder->infoPng; /*UNSAFE copy to avoid having to cleanup! but we will only change primitive parameters, and not invoke the cleanup function nor touch the palette's buffer so we use it safely*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3868
  info.width = w;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3869
  info.height = h;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3870
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3871
  if(encoder->settings.autoLeaveOutAlphaChannel && isFullyOpaque(image, w, h, &encoder->infoRaw.color))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3872
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3873
    /*go to a color type without alpha channel*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3874
    if(info.color.colorType == 6) info.color.colorType = 2;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3875
    else if(info.color.colorType == 4) info.color.colorType = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3876
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3877
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3878
  if(encoder->settings.zlibsettings.windowSize > 32768) { encoder->error = 60; return; } /*error: windowsize larger than allowed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3879
  if(encoder->settings.zlibsettings.btype > 2) { encoder->error = 61; return; } /*error: unexisting btype*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3880
  if(encoder->infoPng.interlaceMethod > 1) { encoder->error = 71; return; } /*error: unexisting interlace mode*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3881
  if((encoder->error = checkColorValidity(info.color.colorType, info.color.bitDepth))) return; /*error: unexisting color type given*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3882
  if((encoder->error = checkColorValidity(encoder->infoRaw.color.colorType, encoder->infoRaw.color.bitDepth))) return; /*error: unexisting color type given*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3883
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3884
  if(!LodePNG_InfoColor_equal(&encoder->infoRaw.color, &info.color))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3885
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3886
    unsigned char* converted;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3887
    size_t size = (w * h * LodePNG_InfoColor_getBpp(&info.color) + 7) / 8;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3888
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3889
    if((info.color.colorType != 6 && info.color.colorType != 2) || (info.color.bitDepth != 8)) { encoder->error = 59; return; } /*for the output image, only these types are supported*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3890
    converted = (unsigned char*)malloc(size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3891
    if(!converted && size) encoder->error = 9955; /*error: malloc failed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3892
    if(!encoder->error) encoder->error = LodePNG_convert(converted, image, &info.color, &encoder->infoRaw.color, w, h);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3893
    if(!encoder->error) preProcessScanlines(&data, &datasize, converted, &info);/*filter(data.data, converted.data, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3894
    free(converted);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3895
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3896
  else preProcessScanlines(&data, &datasize, image, &info);/*filter(data.data, image, w, h, LodePNG_InfoColor_getBpp(&info.color));*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3897
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3898
  ucvector_init(&outv);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3899
  while(!encoder->error) /*not really a while loop, this is only used to break out if an error happens to avoid goto's to do the ucvector cleanup*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3900
  {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3901
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3902
    size_t i;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3903
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3904
    /*write signature and chunks*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3905
    writeSignature(&outv);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3906
    /*IHDR*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3907
    addChunk_IHDR(&outv, w, h, info.color.bitDepth, info.color.colorType, info.interlaceMethod);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3908
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3909
    /*unknown chunks between IHDR and PLTE*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3910
    if(info.unknown_chunks.data[0]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[0], info.unknown_chunks.datasize[0]); if(encoder->error) break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3911
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3912
    /*PLTE*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3913
    if(info.color.colorType == 3)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3914
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3915
      if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3916
      addChunk_PLTE(&outv, &info.color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3917
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3918
    if(encoder->settings.force_palette && (info.color.colorType == 2 || info.color.colorType == 6))
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3919
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3920
      if(info.color.palettesize == 0 || info.color.palettesize > 256) { encoder->error = 68; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3921
      addChunk_PLTE(&outv, &info.color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3922
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3923
    /*tRNS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3924
    if(info.color.colorType == 3 && !isPaletteFullyOpaque(info.color.palette, info.color.palettesize)) addChunk_tRNS(&outv, &info.color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3925
    if((info.color.colorType == 0 || info.color.colorType == 2) && info.color.key_defined) addChunk_tRNS(&outv, &info.color);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3926
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3927
    /*bKGD (must come between PLTE and the IDAt chunks*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3928
    if(info.background_defined) addChunk_bKGD(&outv, &info);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3929
    /*pHYs (must come before the IDAT chunks)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3930
    if(info.phys_defined) addChunk_pHYs(&outv, &info);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3931
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3932
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3933
    /*unknown chunks between PLTE and IDAT*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3934
    if(info.unknown_chunks.data[1]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[1], info.unknown_chunks.datasize[1]); if(encoder->error) break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3935
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3936
    /*IDAT (multiple IDAT chunks must be consecutive)*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3937
    encoder->error = addChunk_IDAT(&outv, data, datasize, &encoder->settings.zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3938
    if(encoder->error) break;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3939
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3940
    /*tIME*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3941
    if(info.time_defined) addChunk_tIME(&outv, &info.time);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3942
    /*tEXt and/or zTXt*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3943
    for(i = 0; i < info.text.num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3944
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3945
      if(strlen(info.text.keys[i]) > 79) { encoder->error = 66; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3946
      if(strlen(info.text.keys[i]) < 1) { encoder->error = 67; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3947
      if(encoder->settings.text_compression)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3948
        addChunk_zTXt(&outv, info.text.keys[i], info.text.strings[i], &encoder->settings.zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3949
      else
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3950
        addChunk_tEXt(&outv, info.text.keys[i], info.text.strings[i]);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3951
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3952
    /*LodePNG version id in text chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3953
    if(encoder->settings.add_id)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3954
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3955
      unsigned alread_added_id_text = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3956
      for(i = 0; i < info.text.num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3957
        if(!strcmp(info.text.keys[i], "LodePNG")) { alread_added_id_text = 1; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3958
      if(alread_added_id_text == 0)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3959
        addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3960
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3961
    /*iTXt*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3962
    for(i = 0; i < info.itext.num; i++)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3963
    {
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3964
      if(strlen(info.itext.keys[i]) > 79) { encoder->error = 66; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3965
      if(strlen(info.itext.keys[i]) < 1) { encoder->error = 67; break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3966
      addChunk_iTXt(&outv, encoder->settings.text_compression,
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3967
                    info.itext.keys[i], info.itext.langtags[i], info.itext.transkeys[i], info.itext.strings[i], 
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3968
                    &encoder->settings.zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3969
    }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3970
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3971
#ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3972
    /*unknown chunks between IDAT and IEND*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3973
    if(info.unknown_chunks.data[2]) { encoder->error = addUnknownChunks(&outv, info.unknown_chunks.data[2], info.unknown_chunks.datasize[2]); if(encoder->error) break; }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3974
#endif /*LODEPNG_COMPILE_UNKNOWN_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3975
    /*IEND*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3976
    addChunk_IEND(&outv);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3977
    
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3978
    break; /*this isn't really a while loop; no error happened so break out now!*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3979
  }
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3980
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3981
  free(data);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3982
  /*instead of cleaning the vector up, give it to the output*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3983
  *out = outv.data;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3984
  *outsize = outv.size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3985
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3986
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3987
unsigned LodePNG_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3988
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3989
  unsigned error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3990
  LodePNG_Encoder encoder;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3991
  LodePNG_Encoder_init(&encoder);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3992
  LodePNG_encode(&encoder, out, outsize, image, w, h);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3993
  error = encoder.error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3994
  LodePNG_Encoder_cleanup(&encoder);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3995
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3996
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3997
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3998
#ifdef LODEPNG_COMPILE_DISK
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  3999
unsigned LodePNG_encode32f(const char* filename, const unsigned char* image, unsigned w, unsigned h)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4000
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4001
  unsigned char* buffer;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4002
  size_t buffersize;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4003
  unsigned error = LodePNG_encode32(&buffer, &buffersize, image, w, h);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4004
  LodePNG_saveFile(buffer, buffersize, filename);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4005
  free(buffer);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4006
  return error;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4007
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4008
#endif /*LODEPNG_COMPILE_DISK*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4009
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4010
void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings* settings)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4011
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4012
  LodeZlib_DeflateSettings_init(&settings->zlibsettings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4013
  settings->autoLeaveOutAlphaChannel = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4014
  settings->force_palette = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4015
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4016
  settings->add_id = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4017
  settings->text_compression = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4018
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4019
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4020
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4021
void LodePNG_Encoder_init(LodePNG_Encoder* encoder)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4022
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4023
  LodePNG_EncodeSettings_init(&encoder->settings);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4024
  LodePNG_InfoPng_init(&encoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4025
  LodePNG_InfoRaw_init(&encoder->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4026
  encoder->error = 1;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4027
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4028
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4029
void LodePNG_Encoder_cleanup(LodePNG_Encoder* encoder)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4030
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4031
  LodePNG_InfoPng_cleanup(&encoder->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4032
  LodePNG_InfoRaw_cleanup(&encoder->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4033
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4034
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4035
void LodePNG_Encoder_copy(LodePNG_Encoder* dest, const LodePNG_Encoder* source)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4036
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4037
  LodePNG_Encoder_cleanup(dest);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4038
  *dest = *source;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4039
  LodePNG_InfoPng_init(&dest->infoPng);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4040
  LodePNG_InfoRaw_init(&dest->infoRaw);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4041
  dest->error = LodePNG_InfoPng_copy(&dest->infoPng, &source->infoPng); if(dest->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4042
  dest->error = LodePNG_InfoRaw_copy(&dest->infoRaw, &source->infoRaw); if(dest->error) return;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4043
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4044
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4045
#endif /*LODEPNG_COMPILE_ENCODER*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4046
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4047
#endif /*LODEPNG_COMPILE_PNG*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4048
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4049
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4050
/* / File IO                                                                / */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4051
/* ////////////////////////////////////////////////////////////////////////// */
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4052
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4053
#ifdef LODEPNG_COMPILE_DISK
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4054
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4055
unsigned LodePNG_loadFile(unsigned char** out, size_t* outsize, const char* filename) /*designed for loading files from hard disk in a dynamically allocated buffer*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4056
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4057
  FILE* file;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4058
  long size;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4059
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4060
  /*provide some proper output values if error will happen*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4061
  *out = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4062
  *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4063
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4064
  file = fopen(filename, "rb");
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4065
  if(!file) return 78;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4066
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4067
  /*get filesize:*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4068
  fseek(file , 0 , SEEK_END);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4069
  size = ftell(file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4070
  rewind(file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4071
  
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4072
  /*read contents of the file into the vector*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4073
  *outsize = 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4074
  *out = (unsigned char*)malloc((size_t)size);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4075
  if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4076
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4077
  fclose(file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4078
  if(!(*out) && size) return 80; /*the above malloc failed*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4079
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4080
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4081
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4082
/*write given buffer to the file, overwriting the file, it doesn't append to it.*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4083
unsigned LodePNG_saveFile(const unsigned char* buffer, size_t buffersize, const char* filename)
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4084
{
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4085
  FILE* file;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4086
  file = fopen(filename, "wb" );
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4087
  if(!file) return 79;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4088
  fwrite((char*)buffer , 1 , buffersize, file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4089
  fclose(file);
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4090
  return 0;
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4091
}
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4092
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4093
#endif /*LODEPNG_COMPILE_DISK*/
42188c7ea2d9 Initial contribution of ORB delivering Feature bug 1460
szarinda <>
parents:
diff changeset
  4094