CHANGELOG.md 14.1 KB
Newer Older
1
2
# The Kaze Changelog

3
4
This project adheres to [Semantic Versioning](http://semver.org).

5
6
7
Here you will find a reverse chronological log of notable additions,
changes, deprecations, removals, and fixes.

8
9
## [Unreleased]
### Added
10
11
- New `KObject` type `KOBJECT_HISTOGRAM` with accompanying
  `khistogram_*()` API (see `khistogram.h`)
12

13
14
15
16
17
18
19
20
- New `KDIMS()` macro for specifying zero terminated Kaze Image
  dimensions.  (`KDIMS()` is a variadic macro for constructing a zero
  terminated `unsigned int[]` compound literal).

- New `KCOORDS()` macro for specifying Kaze Image pixel coordinates.
  (`KCOORDS()` is a variadic macro for constructing an `int[]` compound
  literal).

21
22
23
24
- `KObject` now includes a public `KList` member for use with the
  `klist.h` API.  This allows users to make heterogeneous lists of
  `KObject` types.

25
26
27
28
29
30
31
32
- New `KObject` type `KOBJECT_VALUE` with accompanying `kvalue_*()` API
  (see `kvalue.h`).  Value KObjects provide an abstract encapsulation
  around numbers (both integers and floats) and provides a safe means of
  performing algebra with overflow detection and relative type
  agnosticism.  Both integer and float type math may be performed, with
  certain binary operators promoting the resulting Value KObject to a
  floating point representation for mixed type arithmetic.

33
- Build support under MSVC 2017 Community Edition (and perhaps earlier
34
  editions as well).
35

36
37
38
39
40
41
42
43
44
- New katomics.h header providing `KAZE_ATOMIC_INC_AND_FETCH()` as well
  as `KAZE_ATOMIC_DEC_AND_FETCH()`, which wrap either the corresponding
  gcc builtins or Windows Interlocked facilities.

- New Kaze Shared Object Management API provided by `ksoman.h` provides
  a compatability layer on top of the host OS's dynamic object loading
  facilities (e.g. dlopen, LoadLibrary(), etc)

- Dynamically loadable Kaze module support for Windows!
45

46
47
48
49
50
51
52
53
54
55
56
57
- New `kmodule_depend()` API call allows libkaze users to declare that
  their code depends on a particular module.  Kaze will do its best to
  make the module available, whether the module is internal to libkaze
  or external living on disk in a known location.  `kmodule_depend()`
  also provides a very simple means for modules to declare dependencies
  upon other modules.  This allows a module to pull in other modules as
  necessary -- easily and automatically!

- New `kmodule_unload_all()` has been added, which allows users to
  unload all external Kaze modules that have been loaded by
  `kmodule_depend()` or `kmodule_load()`

58
59
60
61
62
63
64
65
66
67
- New `kimage_value()` has been added, which allows users to grab an
  image pixel value using a Kaze Value object.  This provides the means
  for working with Kaze Images without knowing their pixel type at
  compile time thanks to the generic nature of Kaze Value objects.

- New `kimage_set_value()` has been added, which allows users to set an
  image pixel value using a Kaze Value object.  This provides the means
  for working with a Kaze Image without needing to know its pixel type
  at compile time.

68
69
70
71
72
73
- New KErrorCode `WRONG_KOBJECT_TYPE`, which should be returned by API
  functions when receiving an incorrectly typed `KObject`.

- New `khistogram_from_image()` as been added, which populates a given
  histogram KObject from the values of a specifed image `KObject`.

74
75
76
- New `KObject` type `KOBJECT_DICTIONARY` with accompanying
  `kdictionary_*()` API (see `kdictionary.h`)

77
78
79
80
81
- New KazePy Python module written in Cython provides Python extension
  types wrapping the Kaze API.  Currently Kaze Images and file I/O are
  supported.  See examples/median.py for a simple median filter
  implementation using KazePy!

82
83
84
85
86
- KObjects now have virtual function tables.  This expands upon
  destructors to now include copy constructors.  With this addition also
  comes `kobject_copy()`, which produces deep copies of KObjects using
  the provided KObject's virtual copy constructor method.

87
### Changed
88
89
90
91
92
93
- Make `KObject` the primary data object type.  `KObject` is now used to
  support both Kaze Images and Histograms.  This means that functions
  that once returned or accepted a `KImage` now use `KObject` instead.
  Likewise, Kaze Histograms are also `KObjects`.  Input and output
  buffers to Kaze Blocks are now restricted exclusively to data
  represented by KObject
94

95
96
97
98
99
- `kimage_new()` no longer requires the desired number of dimensions to
  be passed as a parameter.  Instead, image dimensions are now expected
  to be zero terminated.  The KDIMS() macro provides automatic zero
  termination.

100
101
102
103
- Make certain `KObject` attributes private via opaque pointer.  These
  includes the reference count storage, destructor function pointer, and
  object type storage.

104
105
- Make `container_of()` C99 compliant.

106
107
108
109
110
111
112
113
114
- Make `container_of()` work with MSVC (funny how that doesn't come
  automatically with C99 compliance)

- The `klist` API no longer uses `typeof()` due to lack of support from
  MSVC.  Users of the `klist` API must now, therefore, supply an
  additional parameter specifying the type of their housing data
  structure being linked together by `KList` nodes for certain API
  calls. (Aren't you happy that we support more compilers now!?)

115
116
117
118
- Kaze module entry/exit point function table symbols are now mangled
  with the prefix `_kaze_module_` instead of simply `module_` in an
  attempt to respect the common namespace.

119
120
121
122
- The `convolve` Kaze Block module got a rewrite.  A bug was fixed that
  caused the general N-dimensional & type agnostic case give an
  incorrect answer.  Code is more maintainable.

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
- `kblock_set_input()` now only accepts KObject pointers as inputs.  The
  old style of bypassing type checking through use of a variadic
  function was a "bad thing."  KObjects are Kaze's generic type and
  provide enhanced functionality in terms of reference counting.

- `kblock_set_input()` now causes the specified Kaze Block to gain
   ownership over the specified KObject being attached to its input.
   This ownership is released if a subsequent call to
   `kblock_set_input()` attaches a different KObject to the same input
   or if the Kaze Block itself is garbage collected.

- `KBlock` has been renamed `KBlockDefinition`.  Furthermore,
   `KBlockDefinition` is now an internal typedef and is no longer
   exposed through the user API.

- `KIOTerminal` is now an internal typedef and is no longer
   exposed through the user API.

- `KOption` is now an internal typedef and is no longer exposed through
   the user API.

- `KBlockContext` has been renamed `KBlock`.  Furthermore, `KBlock` is
   now a typedef private to `core/kblock.c` and is no longer exposed through
   the user API.  A `KBlock` is now returned to the user as a `KObject`
   with a `KObjectType` of `KOBJECT_BLOCK`.

- Block instance (i.e. context) data is no longer pointed to by an
  opaque `void *` pointer.  Instead, a forward declared `KBlockData *`
  is used in order to ensure type safety and remove the need to up-cast
  from `void *` prior to dereferencing instance data.

- Block developers will notice that entry point functions no longer
  receive a pointer to the calling context.  Instead a `KBlockData *`
  pointing to the calling context's data is received.  This removes the
  burden of casting the `void *` data member of the context.  Block
  authors shouldn't have access context elements outside of the context
  data anyway.

161
162
163
164
165
166
167
- `kimage_write()` has been renamed `kfile_write()` & `kimage_read()`
  has been renamed `kfile_read()`.  Due to the generic nature of
  KObjects and Kaze File I/O modules, these functions can actually be
  used to read and write anything for which a module and suitable
  KObject type exist.  Both `kfile_read()` & `kfile_write()` are
  declared in `kfile.h`.

168
### Deprecated
169
- Nothing Yet!
170
171

### Fixed
172
173
174
175
176
177
178
179
- Bug where `kimage_dim(img, 0)` would return 1 for images with ndim = 0
  Now, 0 is returned because the image contains no pixels.

- Bug where `kimage_dim(img, N)` would return 0 for images where
  ndim != 0 AND N > ndim.  Now, 1 is returned.  This is the correct
  behavior for an existent object being projected into a higher
  dimensionality (i.e. a 2D image projected into 3D space is a slab with
  a thickness of 1).
180
181

### Removed
182
183
184
- The KZipper interface.  C99 compound literals should be used instead.
  Macros `KDIMS()` and `KCOORDS()` wrap compound literal creation for
  this purpose.
185

186
187
188
- Usage of GCC macro expansions in the interest of supporting more
  compilers

189
190
191
192
193
194
- `kmodule_load_bank()` has been removed.  This function is confusing to
  some users.  Its functionality is now performed automatically under
  the hood in a somewhat intelligent fashion.

- `kmodule_unload_bank()` has been removed.

195
196
197
- `kblock_free_context()` -- Kaze Blocks are now a type of `KObject`.
   Consequently, `kobject_release()` must now be used instead.

198
199
200
- `kimage_write()` -- superseded by `kfile_write()`

- `kimage_read()` -- superseded by `kfile_read()`
201

202
## [0.2.0] - 2016-09-12
203
### Added
204
205
206
207
208
209
210
211
212
213
214
- New KImage file operations (`KFileOps`) system, which allows modules
  to extend file format read/write capabilites.  The generic interfaces
  `kimage_read()` and `kimage_write()` check the provided file extension
  and use the corresponding file format module automatically.

- New Module: "PNG", which provides PNG file read/write functionality
  via `kimage_read()` and `kimage_write()`

- New Module: "TIFF", which provides TIFF file read/write functionality
  via `kimage_read()` and `kimage_write()`

215
216
217
- New Module: "downsample", which provides the ability to shrink an image
  by a floating point factor between 0.0001 and 1.0 (eg. 0.01% and 100%)

218
219
220
- KBlock subsystem.  Algorithmic functionality from KModule has been
  moved to the new KBlock subsystem.

221
222
223
224
- New type `KObject`, which can be embedded in a `struct` to provide
  thread safe reference counting and automatic object destruction.
  (See `kobject_obtain()` and `kobject_release()`)

225
226
227
228
- Documentation: New guide `doc/WritingKBlocks.md`

- Documentation: New guide `doc/WritingKFileOps.md`

229
### Changed
230
- Bumped minimum required version of libpng to (>=1.2.9)
231

232
233
234
235
236
- KModule is now generic.  KModules now do not prescribe purpose.
  A KModule can now be used to register new file format I/O capabilities
  with the KImage subsystem or to register a new algorithmic block with
  the KBlock subsystem.

237
- Modules now have a manditory unload hook (called `unload()`)
238

239
- `kmodule_error_handler()` => `kblock_error_handler()`
240

241
- `kmodule_execute()` => `kblock_execute()`
242

243
- `kmodule_free_context()` => `kblock_free_context()`
244

245
- `kmodule_get_output()` => `kblock_get_output()`
246

247
- `kmodule_new_context()` => `kblock_new_context()`
248

249
- `kmodule_set_input()` => `kblock_set_input()`
250

251
- `kmodule_set_option()` => `kblock_set_option()`
252

253
- `kimage_free()` => `kimage_release()`
254

255
256
257
258
259
260
261
- The `convolve` Block was completely rewritten and has been
  greatly simplified

- Completely rewrote CONTRIBUTING.md

- Documentation: Rewrote `doc/ModuleGuide.md`

262
### Fixed
263
- Small memory leak when writing PNG files
264

265
266
267
- Adding library dependencies via `module_link_libraries()` in CMake for
  a disabled module used to throw an error regarding adding link
  libraries to a non-existing build target.  This has been fixed.
268

269
- Bug in `kmodule_load()` that prevented the loading of external modules
270

271
272
273
- Forced C++ linkage imposed by CMake when building `libkaze.so` with
  `Internal` C++ modules

274
### Removed
275
- `load_png()` -- superseded by `kimage_read()`
276

277
- `write_png()` -- superseded by `kimage_write()`
278

279
- `load_tiff()` -- superseded by `kimage_read()`
280

281
- `write_tiff()` -- superseded by `kimage_write()`
282
283


284
## [0.1.0] - 2016-08-30
285
286
287
288
289
290
291
292
293
294
295
### Added
- New type: `KImage`, which provides an N-dimensional, M-channel image
  representation supporting `unsigned char`, `int`, `unsigned int`, and
  `float` pixel types.  Pixel buffers are mutable and can be converted
  between supported types in-place.

- Support for reading/writing `KImage` objects using the PNG file format

- Support for reading/writing `KImage` objects using the TIFF file
  format

296
297
- A dimensionally agnostic iterator for KImages called `KImageIterator`.

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
- KZippers, which provide a limited polymorphic variadic interface for
  functions accepting arrays of numbers.  These provide users of the C
  API with increased usability while maintaining the "wrapability" of
  the core Kaze user API, which avoids variadic functions due to lack of
  interface support from other languages.

- A modular algorithm interface.  Algorithm modules provide a
  standardized data flow model and built-in input validation with
  default value support.

- Build system for modules.  Modules can either be built into the Kaze
  library directly, built as runtime loadable module files, or disabled
  completely.  The default build type can be easily changed in a
  module's CMakeLists.txt.  Custom builds for packaging are easily
  performed by toggling module build modes using `cmake`, `ccmake`, or
  `cmake-gui`.

315
- The ability to write modules in either C or C++
316
317
318
319
320
321
322
323
324

- New type: `KModule`, which is used to define a Kaze module.

- New type: `KModuleContext`, which provides a stateful context of a
  `KModule` implementing an image processing algorithm

- A reasonably sane error code system

- The ability to register an error handler callback function with a
325
  `KModuleContext`, which will automatically be called upon encountering
326
  an error.  Error handler callbacks are automatically passed the
327
  encountered error along with a registered pointer to user data.
328
329
330
331
332
333
334
335

- New type: `KList`, which provides a linked list implementation

- New Module: "average", which provides simple image averaging by
  creating a new image where pixel values are determined by the average
  value of their surrounding neighborhood.  Neighborhood size is an
  option.

336
337
- New Module: "convolve", which performs convolution on an image given a
  kernel
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352

- New Module: "gausskernel", which generates a `KImage` populated with a
  Gaussian kernel of specified standard deviation

- New Module: "sobelkernel", which generates a `KImage` populated with
  Sobel kernels

- New Module: "subtract", which subtracts two images to produce a third

- New Module: "threshold", which performs simple pixel intensity
  thresholding

- New Module: "c_skeleton", which provides a template for module
  developers who want to write a new Kaze module in C.

353
- New Module: "cxx_skeleton", which provides a template for module
354
  developers who want to write a new Kaze module in C++.