xrif
A fast lossless compression system
xrif.c
Go to the documentation of this file.
1 /** \file xrif.c
2  * \brief The eXtreme-ao Reordered Image Format: Definitions
3  *
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  * \ingroup xrif_files
7  */
8 
9 /* This file is part of the xrif library.
10 
11 Copyright (c) 2019, 2020, 2021 The Arizona Board of Regents on behalf of The
12 University of Arizona
13 
14 All rights reserved.
15 
16 Developed by: The Arizona Board of Regents on behalf of the
17 University of Arizona.
18 
19 Redistribution and use for noncommercial purposes in source and
20 binary forms, with or without modification, are permitted provided
21 that the following conditions are met:
22 
23 1. The software is used solely for noncommercial purposes.
24 
25 2. Redistributions of source code must retain the above copyright
26 notice, terms and conditions specified herein and the disclaimer
27 specified in Section 4 below.
28 
29 3. Redistributions in binary form must reproduce the above
30 copyright notice, this list of conditions and the following
31 disclaimer in the documentation and/or other materials provided
32 with the distribution.
33 
34 4. Neither the name of the Arizona Board of Regents, the University
35 of Arizona nor the names of other contributors may be used to
36 endorse or promote products derived from this software without
37 specific prior written permission.
38 
39 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
40 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
41 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
42 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
43 COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
44 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 OF THE POSSIBILITY OF SUCH DAMAGE.
51 
52 Arizona Required Clauses:
53 
54 1.1. Arbitration. The parties agree that if a dispute arises
55 between them concerning this Agreement, the parties may be required
56 to submit the matter to arbitration pursuant to Arizona law.
57 
58 1.2. Applicable Law and Venue. This Agreement shall be interpreted
59 pursuant to the laws of the State of Arizona. Any arbitration or
60 litigation between the Parties shall be conducted in Pima County,
61 ARIZONA, and LICENSEE hereby submits to venue and jurisdiction in
62 Pima County, ARIZONA.
63 
64 1.3. Non-Discrimination. The Parties agree to be bound by state and
65 federal laws and regulations governing equal opportunity and non-
66 discrimination and immigration.
67 
68 1.4. Appropriation of Funds. The Parties recognize that performance
69 by ARIZONA may depend upon appropriation of funds by the State
70 Legislature of ARIZONA. If the Legislature fails to appropriate the
71 necessary funds, or if ARIZONA’S appropriation is reduced during
72 the fiscal year, ARIZONA may cancel this Agreement without further
73 duty or obligation. ARIZONA will notify LICENSEE as soon as
74 reasonably possible after it knows of the loss of funds.
75 
76 1.5. Conflict of Interest. This Agreement is subject to the
77 provisions of A.R.S. 38-511 and other conflict of interest
78 regulations. Within three years of the EFFECTIVE DATE, ARIZONA may
79 cancel this Agreement if any person significantly involved in
80 initiating, negotiating, drafting, securing, or creating this
81 Agreement for or on behalf of ARIZONA becomes an employee or
82 consultant in any capacity of LICENSEE with respect to the subject
83 matter of this Agreement.
84 
85 */
86 
87 #include "xrif.h"
88 
89 #define BIT15 (32768)
90 #define BIT14 (16384)
91 #define BIT13 (8192)
92 #define BIT12 (4096)
93 #define BIT11 (2048)
94 #define BIT10 (1024)
95 #define BIT09 (512)
96 #define BIT08 (256)
97 #define BIT07 (128)
98 #define BIT06 (64)
99 #define BIT05 (32)
100 #define BIT04 (16)
101 #define BIT03 (8)
102 #define BIT02 (4)
103 #define BIT01 (2)
104 #define BIT00 (1)
105 
106 // Allocate an xrif_handle object, which is pointed to by an xrif_t
108 {
109  if( handle_ptr == NULL)
110  {
111  XRIF_ERROR_PRINT("xrif_new", "can not allocate null pointer");
112  return XRIF_ERROR_NULLPTR;
113  }
114 
115  *handle_ptr = (xrif_t) malloc( sizeof(xrif_handle) );
116 
117  if( *handle_ptr == NULL)
118  {
119  XRIF_ERROR_PRINT("xrif_new", "error in malloc");
121  }
122 
123  return xrif_initialize_handle(*handle_ptr);
124 
125 }
126 
127 // Set the basic parameters of an xrif handle
134  )
135 {
136  if( handle == NULL)
137  {
138  XRIF_ERROR_PRINT("xrif_set_size", "can not size null pointer");
139  return XRIF_ERROR_NULLPTR;
140  }
141 
142 
143  if(w == 0 || h == 0 || d == 0 || f == 0)
144  {
145  XRIF_ERROR_PRINT("xrif_set_size", "invalid size");
147  }
148 
149  size_t sz = xrif_typesize(c);
150 
151  if(sz == 0)
152  {
153  XRIF_ERROR_PRINT("xrif_set_size", "invalid type");
155  }
156 
157 
158  handle->width = w;
159  handle->height = h;
160  handle->depth = d;
161  handle->frames = f;
162  handle->type_code = c;
163 
164  handle->data_size = sz;
165 
166  handle->raw_size = w*h*d*f*handle->data_size;
167 
168  return XRIF_NOERROR;
169 }
170 
171 // Configure the difference, reorder, and compression methods.
173  int difference_method,
174  int reorder_method,
175  int compress_method
176  )
177 {
178  if( handle == NULL)
179  {
180  XRIF_ERROR_PRINT("xrif_configure", "can not configure null pointer");
181  return XRIF_ERROR_NULLPTR;
182  }
183 
184  xrif_error_t rv1 = xrif_set_difference_method(handle, difference_method);
185 
186  xrif_error_t rv2 = xrif_set_reorder_method(handle, reorder_method);
187 
188  xrif_error_t rv3 = xrif_set_compress_method(handle, compress_method);
189 
190  if(rv1 != XRIF_NOERROR) return rv1;
191  if(rv2 != XRIF_NOERROR) return rv2;
192  if(rv3 != XRIF_NOERROR) return rv3;
193 
194  return XRIF_NOERROR;
195 
196 }
197 
198 // Allocate all memory buffers according to the configuration specified in the handle.
200 {
201  if( handle == NULL)
202  {
203  XRIF_ERROR_PRINT("xrif_allocate", "can not configure null pointer");
204  return XRIF_ERROR_NULLPTR;
205  }
206 
207  if(handle->width * handle->height * handle->depth * handle->frames * handle->data_size == 0)
208  {
209  XRIF_ERROR_PRINT("xrif_allocate", "the handle is not setup for allocation");
210  return XRIF_ERROR_NOT_SETUP;
211  }
212 
213  xrif_error_t rv;
214 
215  rv = xrif_allocate_raw(handle);
216  if(rv < 0)
217  {
218  XRIF_ERROR_PRINT("xrif_allocate", "error from xrif_allocate_raw");
219  return rv;
220  }
221  rv = xrif_allocate_reordered(handle);
222  if(rv < 0)
223  {
224  XRIF_ERROR_PRINT("xrif_allocate", "error from xrif_allocate_reordered");
225  return rv;
226  }
227 
228  if(handle->compress_on_raw == 0)
229  {
230  rv = xrif_allocate_compressed(handle);
231  if(rv < 0)
232  {
233  XRIF_ERROR_PRINT("xrif_allocate", "error from xrif_allocate_compressed");
234  return rv;
235  }
236  }
237 
238  return XRIF_NOERROR;
239 
240 }
241 
242 // Reset a handle, restoring it to the initialized state. De-allocates owned pointers and re-initializes.
244 {
245  if( handle == NULL)
246  {
247  XRIF_ERROR_PRINT("xrif_allocate", "can not reset null pointer");
248  return XRIF_ERROR_NULLPTR;
249  }
250 
251  if(handle->reordered_buffer && handle->own_reordered)
252  {
253  free(handle->reordered_buffer);
254  }
255 
256  if(handle->raw_buffer && handle->own_raw )
257  {
258  free(handle->raw_buffer);
259  }
260 
261  if(handle->compressed_buffer && handle->own_compressed)
262  {
263  free(handle->compressed_buffer);
264  }
265 
266  int rv = xrif_initialize_handle(handle);
267 
268  if(rv != XRIF_NOERROR)
269  {
270  XRIF_ERROR_PRINT("xrif_reset", "error from xrif_initialize_handle");
271  }
272 
273  return rv;
274 }
275 
276 // De-allocate an xrif_handle object, which is pointed to by an xrif_t
278 {
279  if( handle == NULL)
280  {
281  XRIF_ERROR_PRINT("xrif_delete", "can not delete null pointer.");
282  return XRIF_ERROR_NULLPTR;
283  }
284 
285 
286  xrif_error_t rv = xrif_reset( handle );
287 
288  free(handle);
289 
290  return rv;
291 }
292 
293 // Initialize an xrif handle object.
295 {
296  if( handle == NULL)
297  {
298  XRIF_ERROR_PRINT("xrif_initialize_handle", "can not initialize null pointer");
299  return XRIF_ERROR_NULLPTR;
300  }
301 
302  handle->width = 0;
303  handle->height = 0;
304  handle->depth = 0;
305  handle->frames = 0;
306 
307  handle->type_code = 0;
308 
309  handle->data_size = 0;
310 
311  handle->raw_size = 0;
312  handle->compressed_size = 0;
313 
314  handle->difference_method = XRIF_DIFFERENCE_DEFAULT;
315 
316  handle->reorder_method = XRIF_REORDER_DEFAULT;
317 
318  handle->compress_method = XRIF_COMPRESS_DEFAULT;
319 
320  handle->lz4_acceleration = 1;
321 
322  handle->omp_parallel = 0;
323  handle->omp_numthreads = 1;
324 
325  handle->compress_on_raw = 1;
326 
327  handle->own_raw = 0;
328  handle->raw_buffer = 0;
329  handle->raw_buffer_size = 0;
330 
331  handle->own_reordered = 0;
332  handle->reordered_buffer = 0;
333  handle->reordered_buffer_size = 0;
334 
335  handle->own_compressed = 0;
336  handle->compressed_buffer = 0;
337  handle->compressed_buffer_size = 0;
338 
339  handle->calc_performance = 1;
340 
341  handle->compression_ratio = 0;
342  handle->encode_time = 0;
343  handle->encode_rate = 0;
344  handle->difference_time = 0;
345  handle->difference_rate = 0;
346  handle->reorder_time = 0;
347  handle->reorder_rate = 0;
348  handle->compress_time = 0;
349  handle->compress_rate = 0;
350 
351  return XRIF_NOERROR;
352 }
353 
354 // Set the difference method.
356  int difference_method
357  )
358 {
359  if( handle == NULL)
360  {
361  XRIF_ERROR_PRINT("xrif_set_difference_method", "can not configure null pointer.");
362  return XRIF_ERROR_NULLPTR;
363  }
364 
365 
366  if( difference_method == XRIF_DIFFERENCE_NONE ) handle->difference_method = XRIF_DIFFERENCE_NONE;
367  else if( difference_method == XRIF_DIFFERENCE_DEFAULT ) handle->difference_method = XRIF_DIFFERENCE_DEFAULT;
368  else if( difference_method == XRIF_DIFFERENCE_PREVIOUS ) handle->difference_method = XRIF_DIFFERENCE_PREVIOUS;
369  else if( difference_method == XRIF_DIFFERENCE_FIRST ) handle->difference_method = XRIF_DIFFERENCE_FIRST;
370  else if( difference_method == XRIF_DIFFERENCE_PIXEL ) handle->difference_method = XRIF_DIFFERENCE_PIXEL;
371  else
372  {
373  handle->difference_method = XRIF_DIFFERENCE_DEFAULT;
374  XRIF_ERROR_PRINT("xrif_set_difference_method", "unrecognized difference method. Setting default");
375  return XRIF_ERROR_BADARG;
376  }
377 
378  return XRIF_NOERROR;
379 }
380 
381 // Set the reorder method.
383  int reorder_method
384  )
385 {
386  if( handle == NULL)
387  {
388  XRIF_ERROR_PRINT("xrif_set_reorder_method", "can not configure null pointer");
389  return XRIF_ERROR_NULLPTR;
390  }
391 
392  if( reorder_method == XRIF_REORDER_NONE ) handle->reorder_method = XRIF_REORDER_NONE;
393  else if( reorder_method == XRIF_REORDER_DEFAULT ) handle->reorder_method = XRIF_REORDER_DEFAULT;
394  else if( reorder_method == XRIF_REORDER_BYTEPACK ) handle->reorder_method = XRIF_REORDER_BYTEPACK;
395  else if( reorder_method == XRIF_REORDER_BYTEPACK_RENIBBLE ) handle->reorder_method = XRIF_REORDER_BYTEPACK_RENIBBLE;
396  else if( reorder_method == XRIF_REORDER_BITPACK ) handle->reorder_method = XRIF_REORDER_BITPACK;
397  else
398  {
399  handle->reorder_method = XRIF_REORDER_DEFAULT;
400  XRIF_ERROR_PRINT("xrif_set_reorder_method", "unrecognized reorder method. Setting default");
401  return XRIF_ERROR_BADARG;
402  }
403 
404  return XRIF_NOERROR;
405 }
406 
407 // Set the compress method.
409  int compress_method
410  )
411 {
412  if( handle == NULL)
413  {
414  XRIF_ERROR_PRINT("xrif_set_compress_method", "can not configure null pointer");
415  return XRIF_ERROR_NULLPTR;
416  }
417 
418  if( compress_method == XRIF_COMPRESS_NONE ) handle->compress_method = XRIF_COMPRESS_NONE;
419  else if( compress_method == XRIF_COMPRESS_DEFAULT ) handle->compress_method = XRIF_COMPRESS_DEFAULT;
420  else if( compress_method == XRIF_COMPRESS_LZ4 ) handle->compress_method = XRIF_COMPRESS_LZ4;
421  else
422  {
423  handle->compress_method = XRIF_COMPRESS_DEFAULT;
424  XRIF_ERROR_PRINT("xrif_set_compress_method", "unrecognized compress method. Setting default");
425  return XRIF_ERROR_BADARG;
426  }
427 
428  return XRIF_NOERROR;
429 }
430 
431 // Set the LZ4 acceleration parameter
432 xrif_error_t xrif_set_lz4_acceleration( xrif_t handle, // [in/out] the xrif handle to be configured
433  int32_t lz4_accel // [in] LZ4 acceleration parameter, >=1, higher is faster with less comporession.
434  )
435 {
436  if( handle == NULL)
437  {
438  XRIF_ERROR_PRINT("xrif_set_lz4_acceleration", "can not configure null pointer");
439  return XRIF_ERROR_NULLPTR;
440  }
441 
442  if(lz4_accel < XRIF_LZ4_ACCEL_MIN)
443  {
444  XRIF_ERROR_PRINT("xrif_set_lz4_acceleration", "LZ4 acceleration can't be less than XRIF_LZ4_ACCEL_MIN. Setting to XRIF_LZ4_ACCEL_MIN.");
445  handle->lz4_acceleration = XRIF_LZ4_ACCEL_MIN;
446  return XRIF_ERROR_BADARG;
447  }
448 
449  if(lz4_accel > XRIF_LZ4_ACCEL_MAX) //Max according to LZ4 docs
450  {
451  XRIF_ERROR_PRINT("xrif_set_lz4_acceleration", "LZ4 acceleration can't be greater than XRIF_LZ4_ACCEL_MAX. Setting to XRIF_LZ4_ACCEL_MAX.");
452  handle->lz4_acceleration = XRIF_LZ4_ACCEL_MAX;
453  return XRIF_ERROR_BADARG;
454  }
455 
456  handle->lz4_acceleration = lz4_accel;
457 
458  return XRIF_NOERROR;
459 }
460 
461 // Calculate the minimum size of the raw buffer.
462 size_t xrif_min_raw_size(xrif_t handle)
463 {
464  if(handle->compress_on_raw == 0) //Won't use raw to store compressed data
465  {
466  return handle->width * handle->height * handle->depth * handle->frames * handle->data_size;
467  }
468  else
469  {
470  //In this case it depends on size needed for compression.
471  size_t minSz = xrif_min_compressed_size(handle);
472 
473  if(minSz < handle->width * handle->height * handle->depth * handle->frames * handle->data_size)
474  {
475  minSz = handle->width * handle->height * handle->depth * handle->frames * handle->data_size;
476  }
477 
478  return minSz;
479  }
480 
481  return 0;
482 }
483 
484 // Calculate the minimum size of the reordered buffer.
486 {
487  if(handle == NULL) return 0;
488 
489  if(handle->reorder_method == XRIF_REORDER_NONE)
490  {
491  return handle->width * handle->height * handle->depth * handle->frames * handle->data_size;
492  }
493 
494  if(handle->reorder_method == XRIF_REORDER_BYTEPACK)
495  {
496  size_t one_frame = handle->width*handle->height*handle->depth*handle->data_size;
497 
498  return one_frame * (handle->frames);
499  }
500 
501  if(handle->reorder_method == XRIF_REORDER_BYTEPACK_RENIBBLE)
502  {
503  size_t one_frame = handle->width * handle->height * handle->depth * handle->data_size;
504 
505  return one_frame * (handle->frames+1); //Allocating an extra frame to allow for odd number of pixels in reorder step
506  }
507 
508  if(handle->reorder_method == XRIF_REORDER_BITPACK)
509  {
510  size_t one_frame = handle->width * handle->height * handle->depth * handle->data_size;
511 
512  if(one_frame < 16) one_frame = 16; //Handle cases where too little data is available for bitpacking.
513 
514  return one_frame * (handle->frames+1); //Allocating an extra frame to allow for odd number of pixels in reorder step
515  }
516 
517  return 0;
518 }
519 
520 /// Calculate the minimum size of the compressed buffer.
522 {
523  if(handle->compress_method == XRIF_COMPRESS_NONE)
524  {
525  return handle->width * handle->height * handle->depth * handle->frames * handle->data_size;
526  }
527 
528  if(handle->compress_method == XRIF_COMPRESS_LZ4)
529  {
530  //We compress the reordered buffer, and it can be the largest buffer.
531  return LZ4_compressBound(xrif_min_reordered_size(handle));
532  }
533 
534  return 0;
535 }
536 
537 // Set the raw data buffer to a pre-allocated pointer
539  void * raw,
540  size_t size
541  )
542 {
543  if( handle == NULL)
544  {
545  XRIF_ERROR_PRINT("xrif_set_raw", "can not configure null pointer");
546  return XRIF_ERROR_NULLPTR;
547  }
548 
549  if(handle->raw_buffer && handle->own_raw )
550  {
551  free(handle->raw_buffer);
552  }
553 
554  handle->own_raw = 0;
555 
556  handle->raw_buffer = raw;
557 
558  handle->raw_buffer_size = size;
559 
560  if((handle->raw_buffer != NULL && handle->raw_buffer_size == 0) || (handle->raw_buffer == 0 && handle->raw_buffer_size != 0))
561  {
562  XRIF_ERROR_PRINT("xrif_set_raw", "the size is not valid");
564  }
565 
566  //Check if we meet minimum size requirement based on compress_on_raw value
567  size_t minSz = xrif_min_raw_size(handle);
568  if(minSz == 0)
569  {
570  XRIF_ERROR_PRINT("xrif_set_raw", "error calculating minimum raw buffer size - check configuration.");
572  }
573 
574  if(handle->raw_buffer_size < minSz)
575  {
576  XRIF_ERROR_PRINT("xrif_set_raw", "the raw buffer size is too small for configured parameters");
578  }
579 
580  return XRIF_NOERROR;
581 }
582 
583 // Allocate the raw buffer based on the already set stream dimensions.
585 {
586  if( handle == NULL)
587  {
588  XRIF_ERROR_PRINT("xrif_allocate_raw", "can not configure null pointer");
589  return XRIF_ERROR_NULLPTR;
590  }
591 
592  if(handle->width * handle->height * handle->depth * handle->frames * handle->data_size == 0)
593  {
594  XRIF_ERROR_PRINT("xrif_allocate_raw", "the handle is not setup for allocation");
595  return XRIF_ERROR_NOT_SETUP;
596  }
597 
598  if(handle->raw_buffer && handle->own_raw )
599  {
600  free(handle->raw_buffer);
601  }
602 
603  handle->raw_buffer_size = xrif_min_raw_size(handle);
604  if(handle->raw_buffer_size == 0)
605  {
606  XRIF_ERROR_PRINT("xrif_allocate_raw", "error calculating minimum raw buffer size - check configuration.");
608  }
609 
610  handle->raw_buffer = (char *) malloc( handle->raw_buffer_size );
611 
612  if(handle->raw_buffer == NULL)
613  {
614  handle->own_raw = 0;
615 
616  XRIF_ERROR_PRINT("xrif_allocate_raw", "error from malloc");
617 
618  return XRIF_ERROR_MALLOC;
619  }
620 
621  handle->own_raw = 1;
622 
623  return XRIF_NOERROR;
624 }
625 
626 // Set the rordered (working) data buffer to a pre-allocated pointer
628  void * reordered,
629  size_t size
630  )
631 {
632  if( handle == NULL)
633  {
634  XRIF_ERROR_PRINT("xrif_set_reordered", "can not configure null pointer");
635  return XRIF_ERROR_NULLPTR;
636  }
637 
638  if(handle->reordered_buffer && handle->own_reordered )
639  {
640  free(handle->reordered_buffer);
641  }
642 
643  handle->reordered_buffer = reordered;
644 
645  handle->reordered_buffer_size = size;
646 
647  handle->own_reordered = 0;
648 
649  if((handle->reordered_buffer != NULL && handle->reordered_buffer_size == 0) || (handle->reordered_buffer == 0 && handle->reordered_buffer_size != 0))
650  {
651  XRIF_ERROR_PRINT("xrif_set_reordered", "the size is not valid");
653  }
654 
655  //Check minimum size for reordering algorithms to work.
656  size_t minSz = xrif_min_reordered_size(handle);
657  if(minSz == 0)
658  {
659  XRIF_ERROR_PRINT("xrif_set_reordered", "error calculating minimum reordered buffer size - check configuration.");
661  }
662 
663  if(handle->reordered_buffer_size < minSz)
664  {
665  XRIF_ERROR_PRINT("xrif_set_reordered", "the reordered buffer size is too small for configured parameters");
667  }
668 
669  return XRIF_NOERROR;
670 }
671 
672 // Allocate the reordered buffer based on the already set stream dimensions.
674 {
675  if( handle == NULL)
676  {
677  XRIF_ERROR_PRINT("xrif_allocate_reordered", "can not configure null pointer");
678  return XRIF_ERROR_NULLPTR;
679  }
680 
681  if(handle->width * handle->height * handle->depth * handle->frames * handle->data_size == 0)
682  {
683  XRIF_ERROR_PRINT("xrif_allocate_reordered", "the handle is not setup for allocation");
684  return XRIF_ERROR_NOT_SETUP;
685  }
686 
687  if(handle->reordered_buffer && handle->own_reordered)
688  {
689  free(handle->reordered_buffer);
690  }
691 
693  if(handle->reordered_buffer_size == 0)
694  {
695  XRIF_ERROR_PRINT("xrif_allocate_reordered", "error calculating minimum reordered buffer size - check configuration.");
697  }
698 
699  handle->reordered_buffer = (char *) malloc( handle->reordered_buffer_size );
700 
701  if(handle->reordered_buffer == NULL)
702  {
703  handle->reordered_buffer_size = 0;
704  handle->own_reordered = 0;
705 
706  XRIF_ERROR_PRINT("xrif_allocate_reordered", "error from malloc");
707  return XRIF_ERROR_MALLOC;
708  }
709 
710  handle->own_reordered = 1;
711 
712  return XRIF_NOERROR;
713 }
714 
716  void * compressed,
717  size_t size
718  )
719 {
720 
721  if( handle == NULL)
722  {
723  XRIF_ERROR_PRINT("xrif_set_compressed", "can not configure null pointer");
724  return XRIF_ERROR_NULLPTR;
725  }
726 
727  if(handle->compressed_buffer && handle->own_compressed )
728  {
729  free(handle->compressed_buffer);
730  }
731 
732  handle->own_compressed = 0;
733 
734  handle->compressed_buffer = compressed;
735 
736  handle->compressed_buffer_size = size;
737 
738  if((handle->compressed_buffer != NULL && handle->compressed_buffer_size == 0) || (handle->compressed_buffer == 0 && handle->compressed_buffer_size != 0))
739  {
740  XRIF_ERROR_PRINT("xrif_set_compressed", "the size is not valid");
742  }
743 
744  size_t minSz = xrif_min_compressed_size(handle);
745  if(minSz == 0)
746  {
747  XRIF_ERROR_PRINT("xrif_set_compressed", "error calculating minimum compressed buffer size - check configuration.");
749  }
750 
751  if(handle->compressed_buffer_size < minSz)
752  {
753  XRIF_ERROR_PRINT("xrif_set_compressed", "the compressed buffer size is too small for configured parameters");
755  }
756 
757  return XRIF_NOERROR;
758 }
759 
761 {
762  if( handle == NULL)
763  {
764  XRIF_ERROR_PRINT("xrif_allocate_compressed", "can not configure null pointer");
765  return XRIF_ERROR_NULLPTR;
766  }
767 
768  if(handle->compressed_buffer && handle->own_compressed )
769  {
770  free(handle->compressed_buffer);
771  }
772 
773  if(handle->width * handle->height * handle->depth * handle->frames * handle->data_size == 0)
774  {
775  XRIF_ERROR_PRINT("xrif_allocate_compressed", "the handle is not setup for allocation");
776  return XRIF_ERROR_NOT_SETUP;
777  }
778 
780  if(handle->compressed_buffer_size == 0)
781  {
782  XRIF_ERROR_PRINT("xrif_allocate_compressed", "error calculating minimum compressed buffer size - check configuration.");
784  }
785 
786  handle->compressed_buffer = (char *) malloc( handle->compressed_buffer_size );
787 
788  if(handle->compressed_buffer == NULL)
789  {
790  handle->own_compressed = 0;
791 
792  XRIF_ERROR_PRINT("xrif_allocate_compressed", "error from malloc");
793  return XRIF_ERROR_MALLOC;
794  }
795 
796  handle->own_compressed = 1;
797 
798  return XRIF_NOERROR;
799 }
800 
802 {
803  if( handle == NULL)
804  {
805  XRIF_ERROR_PRINT("xrif_width", "can not access a null pointer");
806  return XRIF_ERROR_NULLPTR;
807  }
808 
809  return handle->width;
810 }
811 
813 {
814  if( handle == NULL)
815  {
816  XRIF_ERROR_PRINT("xrif_height", "can not access a null pointer");
817  return XRIF_ERROR_NULLPTR;
818  }
819 
820  return handle->height;
821 }
822 
824 {
825  if( handle == NULL)
826  {
827  XRIF_ERROR_PRINT("xrif_depth", "can not access a null pointer");
828  return XRIF_ERROR_NULLPTR;
829  }
830 
831  return handle->depth;
832 }
833 
835 {
836  if( handle == NULL)
837  {
838  XRIF_ERROR_PRINT("xrif_frames", "can not access a null pointer");
839  return XRIF_ERROR_NULLPTR;
840  }
841 
842  return handle->frames;
843 }
844 
845 // Populate a header buffer with the xrif protocol details.
847  xrif_t handle
848  )
849 {
850  if( header == NULL)
851  {
852  XRIF_ERROR_PRINT("xrif_write_header", "can not write to a null pointer");
853  return XRIF_ERROR_NULLPTR;
854  }
855 
856  if( handle == NULL)
857  {
858  XRIF_ERROR_PRINT("xrif_write_header", "can not read from a null pointer handle");
859  return XRIF_ERROR_NULLPTR;
860  }
861 
862  header[0] = 'x';
863  header[1] = 'r';
864  header[2] = 'i';
865  header[3] = 'f';
866 
867  *((uint32_t *) &header[4]) = XRIF_VERSION;
868 
869  *((uint32_t *) &header[8]) = XRIF_HEADER_SIZE;
870 
871  *((uint32_t *) &header[12]) = handle->width;
872 
873  *((uint32_t *) &header[16]) = handle->height;
874 
875  *((uint32_t *) &header[20]) = handle->depth;
876 
877  *((uint32_t *) &header[24]) = handle->frames;
878 
879  *((uint16_t *) &header[28]) = handle->type_code;
880 
881  *((int16_t *) &header[30]) = handle->difference_method;
882 
883  *((int16_t *) &header[32]) = handle->reorder_method;
884 
885  *((int16_t *) &header[34]) = handle->compress_method;
886 
887  *((uint32_t *) &header[36]) = handle->compressed_size;
888 
889  memset(&header[40], 0, 8);
890 
891  if(handle->compress_method == XRIF_COMPRESS_LZ4)
892  {
893  *((uint16_t *) &header[40]) = handle->lz4_acceleration;
894  }
895 
896  return XRIF_NOERROR;
897 
898 }
899 
900 //Configure an xrif handle by reading a xrif protocol header
902  uint32_t * header_size,
903  char * header
904  )
905 {
906  if( handle == NULL)
907  {
908  XRIF_ERROR_PRINT("xrif_read_header", "can not configure a null pointer handle");
909  return XRIF_ERROR_NULLPTR;
910  }
911 
912  if( header_size == NULL)
913  {
914  XRIF_ERROR_PRINT("xrif_read_header", "can not configure a null pointer uint32_t");
915  return XRIF_ERROR_NULLPTR;
916  }
917 
918  if( header == NULL)
919  {
920  XRIF_ERROR_PRINT("xrif_read_header", "can not read from a null pointer");
921  return XRIF_ERROR_NULLPTR;
922  }
923 
924  if( header[0] != 'x' || header[1] != 'r' || header[2] != 'i' || header[3] != 'f')
925  {
926  XRIF_ERROR_PRINT("xrif_read_header", "xrif magic number not present");
927  return XRIF_ERROR_BADHEADER;
928  }
929 
930  if( *((uint32_t *) &header[4]) > XRIF_VERSION)
931  {
932  XRIF_ERROR_PRINT("xrif_read_header", "xrif version too high");
934  }
935 
936  *header_size = *((uint32_t *) &header[8]);
937 
938  handle->width = *((uint32_t *) &header[12]);
939 
940  handle->height = *((uint32_t *) &header[16]);
941 
942  handle->depth = *((uint32_t *) &header[20]);
943 
944  handle->frames = *((uint32_t *) &header[24]);
945 
946  handle->type_code = *((uint16_t *) &header[28]);
947 
948  handle->data_size = xrif_typesize(handle->type_code);
949 
950  handle->difference_method = *((int16_t *) &header[30]);
951 
952  handle->reorder_method = *((int16_t *) &header[32]);
953 
954  handle->compress_method = *((int16_t *) &header[34]);
955 
956  handle->compressed_size = *((uint32_t *) &header[36]);
957 
958  if(handle->compress_method == XRIF_COMPRESS_LZ4)
959  {
960  handle->lz4_acceleration = *((uint16_t *) &header[40]);
961  }
962 
963  return XRIF_NOERROR;
964 }
965 
967 {
968  if( handle == NULL)
969  {
970  XRIF_ERROR_PRINT("xrif_encode", "can not use a null pointer");
971  return XRIF_ERROR_NULLPTR;
972  }
973 
974  xrif_error_t rv;
975 
976  clock_gettime(CLOCK_REALTIME, &handle->ts_difference_start);
977 
978  if( handle->difference_method == XRIF_DIFFERENCE_NONE && handle->reorder_method == XRIF_REORDER_NONE && handle->compress_method == XRIF_COMPRESS_NONE)
979  {
980  //Set compressed size.
981  handle->compressed_size = handle->width * handle->height * handle->depth * handle->frames * handle->data_size;
982 
983 
984  if(handle->calc_performance)
985  {
986  //So that we have some non-inifinities in the performance metrics.
987  clock_gettime(CLOCK_REALTIME, &handle->ts_reorder_start);
988  clock_gettime(CLOCK_REALTIME, &handle->ts_compress_start);
989  clock_gettime(CLOCK_REALTIME, &handle->ts_compress_done);
990  }
991 
992  //but otherwise do nothing.
993  }
994  else
995  {
996  rv = xrif_difference( handle);
997 
998  if( rv != XRIF_NOERROR )
999  {
1000  XRIF_ERROR_PRINT("xrif_encode", "error in xrif_difference");
1001  return rv;
1002  }
1003 
1004  clock_gettime(CLOCK_REALTIME, &handle->ts_reorder_start);
1005 
1006  rv = xrif_reorder(handle);
1007 
1008  if( rv != XRIF_NOERROR )
1009  {
1010  XRIF_ERROR_PRINT("xrif_encode", "error in xrif_reorder");
1011  return rv;
1012  }
1013 
1014  clock_gettime(CLOCK_REALTIME, &handle->ts_compress_start);
1015 
1016  rv = xrif_compress(handle);
1017 
1018  if( rv != XRIF_NOERROR )
1019  {
1020  XRIF_ERROR_PRINT("xrif_encode", "error in xrif_compress");
1021  return rv;
1022  }
1023 
1024  clock_gettime(CLOCK_REALTIME, &handle->ts_compress_done);
1025  }
1026 
1027  if(handle->calc_performance)
1028  {
1029  handle->compression_ratio = xrif_compression_ratio(handle);
1030  handle->encode_time = xrif_encode_time(handle);
1031  handle->encode_rate = xrif_encode_rate(handle);
1032  handle->difference_time = xrif_difference_time(handle);
1033  handle->difference_rate = xrif_difference_rate(handle);
1034  handle->reorder_time = xrif_reorder_time(handle);
1035  handle->reorder_rate = xrif_reorder_rate(handle);
1036  handle->compress_time = xrif_compress_time(handle);
1037  handle->compress_rate = xrif_compress_rate(handle);
1038  }
1039 
1040  return XRIF_NOERROR;
1041 }
1042 
1044 {
1045  if( handle == NULL)
1046  {
1047  XRIF_ERROR_PRINT("xrif_encode", "can not use a null pointer");
1048  return XRIF_ERROR_NULLPTR;
1049  }
1050 
1051  xrif_error_t rv;
1052 
1053  clock_gettime(CLOCK_REALTIME, &handle->ts_decompress_start);
1054 
1055  if( handle->difference_method == XRIF_DIFFERENCE_NONE && handle->reorder_method == XRIF_REORDER_NONE && handle->compress_method == XRIF_COMPRESS_NONE)
1056  {
1057  if(handle->calc_performance)
1058  {
1059  //So that we have some non-inifinities in the performance metrics.
1060  clock_gettime(CLOCK_REALTIME, &handle->ts_unreorder_start);
1061  clock_gettime(CLOCK_REALTIME, &handle->ts_undifference_start);
1062  clock_gettime(CLOCK_REALTIME, &handle->ts_undifference_done);
1063  }
1064 
1065  //but otherwise do nothing.
1066  }
1067  else
1068  {
1069  rv = xrif_decompress(handle);
1070 
1071  if( rv != XRIF_NOERROR )
1072  {
1073  fprintf(stderr, "xrif_decode: error returned by xrif_decompress\n");
1074  return rv;
1075  }
1076  clock_gettime(CLOCK_REALTIME, &handle->ts_unreorder_start);
1077 
1078  rv = xrif_unreorder(handle);
1079 
1080  if( rv != XRIF_NOERROR )
1081  {
1082  fprintf(stderr, "xrif_decode: error returned by xrif_unreorder\n");
1083  return rv;
1084  }
1085 
1086  clock_gettime(CLOCK_REALTIME, &handle->ts_undifference_start);
1087 
1088  rv = xrif_undifference(handle);
1089 
1090  if( rv != XRIF_NOERROR )
1091  {
1092  fprintf(stderr, "xrif_decode: error returned by xrif_undifference\n");
1093  return rv;
1094  }
1095 
1096  clock_gettime(CLOCK_REALTIME, &handle->ts_undifference_done);
1097  }
1098 
1099  return XRIF_NOERROR;
1100 }
1101 
1103 {
1104  if( handle == NULL)
1105  {
1106  XRIF_ERROR_PRINT("xrif_difference", "can not use a null pointer");
1107  return XRIF_ERROR_NULLPTR;
1108  }
1109 
1110  int method = handle->difference_method;
1111 
1112  if(method == 0) method = XRIF_DIFFERENCE_DEFAULT;
1113 
1114  switch( method )
1115  {
1116  case XRIF_DIFFERENCE_NONE:
1117  return XRIF_NOERROR;
1118  case XRIF_DIFFERENCE_PREVIOUS:
1119  return xrif_difference_previous(handle);
1120  case XRIF_DIFFERENCE_FIRST:
1121  return xrif_difference_first(handle);
1122  case XRIF_DIFFERENCE_PIXEL:
1123  return xrif_difference_pixel(handle);
1124  default:
1125  return XRIF_ERROR_NOTIMPL;
1126  }
1127 }
1128 
1130 {
1131  if( handle == NULL)
1132  {
1133  XRIF_ERROR_PRINT("xrif_undifference", "can not use a null pointer");
1134  return XRIF_ERROR_NULLPTR;
1135  }
1136 
1137  int method = handle->difference_method;
1138 
1139  if(method == 0) method = XRIF_DIFFERENCE_DEFAULT;
1140 
1141  switch( method )
1142  {
1143  case XRIF_DIFFERENCE_NONE:
1144  return XRIF_NOERROR;
1145  case XRIF_DIFFERENCE_PREVIOUS:
1146  return xrif_undifference_previous(handle);
1147  case XRIF_DIFFERENCE_FIRST:
1148  return xrif_undifference_first(handle);
1149  case XRIF_DIFFERENCE_PIXEL:
1150  return xrif_undifference_pixel(handle);
1151  default:
1152  return XRIF_ERROR_NOTIMPL;
1153  }
1154 }
1155 
1156 xrif_error_t xrif_difference_sint16_rgb( xrif_t handle )
1157 {
1158  size_t npix = handle->width*handle->height;
1159 
1160  for(int n=0; n < handle->frames-1; ++n)
1161  {
1162  if( (handle->frames - 1 - n) % 3 == 0)
1163  {
1164  size_t n_stride0 = (handle->frames - 4 - n) * npix;
1165  size_t n_stride = (handle->frames - 1 - n) * npix;
1166 
1167  for(int ii=0; ii< handle->width; ++ii)
1168  {
1169  size_t ii_stride = ii*handle->height;
1170 
1171  for(int jj=0; jj< handle->height; ++jj)
1172  {
1173  size_t idx0 = n_stride0 + ii_stride + jj;
1174  size_t idx = n_stride + ii_stride + jj;
1175 
1176  ((int16_t *) handle->raw_buffer)[idx] = (((int16_t *)handle->raw_buffer)[idx] - ((int16_t*)handle->raw_buffer)[idx0]);
1177  }
1178  }
1179  }
1180  else
1181  {
1182  size_t n_stride0 = (handle->frames - 2 - n) * npix;
1183  size_t n_stride = (handle->frames - 1 - n) * npix;
1184 
1185 
1186  for(int ii=0; ii< handle->width; ++ii)
1187  {
1188  size_t ii_stride = ii*handle->height;
1189 
1190  for(int jj=0; jj< handle->height; ++jj)
1191  {
1192  size_t idx0 = n_stride0 + ii_stride + jj;
1193  size_t idx = n_stride + ii_stride + jj;
1194 
1195  ((int16_t *) handle->raw_buffer)[idx] = (((int16_t *)handle->raw_buffer)[idx] - ((int16_t*)handle->raw_buffer)[idx0]);
1196  }
1197  }
1198  }
1199  }
1200 
1201  for(int n=0; n < handle->frames-3; ++n)
1202  {
1203  if( (handle->frames - 1 - n) % 3 == 0) continue;
1204  else
1205  {
1206  size_t n_stride0 = (handle->frames - 4 - n) * npix;
1207  size_t n_stride = (handle->frames - 1 - n) * npix;
1208 
1209 
1210  for(int ii=0; ii< handle->width; ++ii)
1211  {
1212  size_t ii_stride = ii*handle->height;
1213 
1214  for(int jj=0; jj< handle->height; ++jj)
1215  {
1216  size_t idx0 = n_stride0 + ii_stride + jj;
1217  size_t idx = n_stride + ii_stride + jj;
1218 
1219  ((int16_t *) handle->raw_buffer)[idx] = (((int16_t *)handle->raw_buffer)[idx] - ((int16_t*)handle->raw_buffer)[idx0]);
1220  }
1221  }
1222  }
1223  }
1224  return XRIF_NOERROR;
1225 }
1226 
1228 {
1229  int method = handle->reorder_method;
1230 
1231  if(method == 0) method = XRIF_REORDER_DEFAULT;
1232 
1233  switch( method )
1234  {
1235  case XRIF_REORDER_NONE:
1236  return xrif_reorder_none(handle);
1237  case XRIF_REORDER_BYTEPACK:
1238  return xrif_reorder_bytepack(handle);
1239  case XRIF_REORDER_BYTEPACK_RENIBBLE:
1240  return xrif_reorder_bytepack_renibble(handle);
1241  case XRIF_REORDER_BITPACK:
1242  return xrif_reorder_bitpack(handle);
1243  default:
1244  return XRIF_ERROR_NOTIMPL;
1245  }
1246 }
1247 
1249 {
1250  int method = handle->reorder_method;
1251 
1252  if(method == 0) method = XRIF_REORDER_DEFAULT;
1253 
1254  switch( method )
1255  {
1256  case XRIF_REORDER_NONE:
1257  return xrif_unreorder_none(handle);
1258  case XRIF_REORDER_BYTEPACK:
1259  return xrif_unreorder_bytepack(handle);
1260  case XRIF_REORDER_BYTEPACK_RENIBBLE:
1261  return xrif_unreorder_bytepack_renibble(handle);
1262  case XRIF_REORDER_BITPACK:
1263  return xrif_unreorder_bitpack(handle);
1264  default:
1265  return XRIF_ERROR_NOTIMPL;
1266  }
1267 }
1268 
1269 /// Perform no re-ordering, simply copy raw to reordered.
1271 {
1272  size_t npix = handle->width * handle->height * handle->depth * handle->frames;
1273 
1274  if( handle == NULL)
1275  {
1276  return XRIF_ERROR_NULLPTR;
1277  }
1278 
1279  if( handle->raw_buffer_size < npix*handle->data_size )
1280  {
1282  }
1283 
1284  if( handle->reordered_buffer_size < npix*handle->data_size )
1285  {
1287  }
1288 
1289  memcpy(handle->reordered_buffer, handle->raw_buffer, npix*handle->data_size);
1290 
1291  //Zero the rest of the reordered buffer.
1292  if(handle->reordered_buffer_size > npix*handle->data_size)
1293  {
1294  memset(handle->reordered_buffer + npix*handle->data_size, 0, handle->reordered_buffer_size-npix*handle->data_size);
1295  }
1296 
1297  return XRIF_NOERROR;
1298 }
1299 
1300 //--------------------------------------------------------------------
1301 // bytepack reodering
1302 //--------------------------------------------------------------------
1303 
1304 //Dispatch bytepack reordering according to type
1306 {
1307  if( handle == NULL)
1308  {
1309  XRIF_ERROR_PRINT("xrif_reorder_bytepack", "can not use a null pointer");
1310  return XRIF_ERROR_NULLPTR;
1311  }
1312 
1313  if(handle->type_code == XRIF_TYPECODE_INT16 || handle->type_code == XRIF_TYPECODE_UINT16)
1314  {
1315  return xrif_reorder_bytepack_sint16(handle);
1316  }
1317  else if(handle->type_code == XRIF_TYPECODE_INT32 || handle->type_code == XRIF_TYPECODE_UINT32)
1318  {
1319  XRIF_ERROR_PRINT("xrif_reorder_bytepack", "bytepack reordering not implemented for 32 bit ints");
1320  return XRIF_ERROR_NOTIMPL;
1321  }
1322  else if(handle->type_code == XRIF_TYPECODE_INT64 || handle->type_code == XRIF_TYPECODE_UINT64)
1323  {
1324  XRIF_ERROR_PRINT("xrif_reorder_bytepack", "bytepack reordering not implemented for 64 bit ints");
1325  return XRIF_ERROR_NOTIMPL;
1326  }
1327  else
1328  {
1329  XRIF_ERROR_PRINT("xrif_reorder_bytepack", "bytepack reordering not implemented for type");
1330  return XRIF_ERROR_NOTIMPL;
1331  }
1332 
1333 }
1334 
1335 //Bytepack reodering for 16 bit ints
1337 {
1338  size_t one_frame, npix;
1339 
1340  if( handle == NULL)
1341  {
1342  XRIF_ERROR_PRINT("xrif_reorder_bytepack_sint16", "can not use a null pointer");
1343  return XRIF_ERROR_NULLPTR;
1344  }
1345 
1346  //If it's pixel, we reorder the first frame too.
1347  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1348  {
1349  one_frame = 0;
1350  npix = handle->width * handle->height * handle->depth * handle->frames;
1351  }
1352  else //Otherwise we don't include the first frame in the re-ordering
1353  {
1354  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1355  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1356  }
1357 
1358  if( handle->raw_buffer_size < one_frame + npix*handle->data_size )
1359  {
1361  }
1362 
1363  if( handle->reordered_buffer_size < one_frame + npix*handle->data_size )
1364  {
1366  }
1367 
1368  char * raw_buffer = handle->raw_buffer + one_frame ;
1369  char * reordered_buffer = handle->reordered_buffer + one_frame;
1370  char * reordered_buffer2 = reordered_buffer + npix;
1371 
1372  ///\todo is this actually necessary, and can this can be just the extra pixels?
1373  //Zero the reordered buffer.
1374  //memset(handle->reordered_buffer, 0, handle->reordered_buffer_size);
1375 
1376  //Set the first part of the reordered buffer to the first frame (always the reference frame)
1377  memcpy(handle->reordered_buffer,handle->raw_buffer, one_frame);
1378 
1379  #ifndef XRIF_NO_OMP
1380  #pragma omp parallel if (handle->omp_parallel > 0)
1381  {
1382  #pragma omp for
1383  #endif
1384  for(size_t pix = 0; pix < npix; ++pix)
1385  {
1386  //Note: a lookup table for this was found to be 2x slower than the following algorithm.
1387  int_fast8_t x2 = raw_buffer[2*pix];
1388  int_fast8_t x1 = raw_buffer[2*pix+1];
1389 
1390  if(x2 < 0)
1391  {
1392  if(x1 == -1) x1 = 0;
1393  else if(x1 == 0) x1 = -1;
1394  }
1395 
1396  reordered_buffer[pix] = x2;
1397  reordered_buffer2[pix] = x1;
1398 
1399 
1400  }
1401 
1402  #ifndef XRIF_NO_OMP
1403  }
1404  #endif
1405 
1406  return XRIF_NOERROR;
1407 }
1408 
1410 {
1411  //The lookup table, a static array
1412  #include "bitshift_and_nibbles.inc"
1413 
1414  size_t one_frame, npix;
1415 
1416  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1417  {
1418  one_frame = 0;
1419  npix = handle->width * handle->height * handle->depth * handle->frames;
1420  }
1421  else
1422  {
1423  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1424  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1425  }
1426 
1427 
1428  if( handle->raw_buffer_size < one_frame + npix*handle->data_size )
1429  {
1431  }
1432 
1433  //The reordered buffer must be frames+1 big to be sure it can handle odd sizes.
1434  if( handle->reordered_buffer_size < xrif_min_reordered_size(handle) )
1435  {
1437  }
1438  //Zero the reordered buffer.
1439  memset(handle->reordered_buffer,0, xrif_min_reordered_size(handle));
1440 
1441  int16_t * raw_buffer = (int16_t*)(handle->raw_buffer + one_frame);
1442 
1443  //Get pointer that starts one image into the handle->reordered_buffer. This area is 2*npix bytes long
1444  unsigned char * reordered_buffer = (unsigned char *) handle->reordered_buffer + one_frame;
1445 
1446  //Get point that starts halfway through, splitting at npix bytes
1447  unsigned char * reordered_buffer2 = (unsigned char*) reordered_buffer + npix;
1448 
1449  //Set the first part of the reordered buffer to the first frame (always the reference frame)
1450  /*for(size_t pix=0; pix< one_frame; ++pix)
1451  {
1452  handle->reordered_buffer[pix] = handle->raw_buffer[pix];
1453  }*/
1454  memcpy(handle->reordered_buffer, handle->raw_buffer, one_frame);
1455 
1456  //Corrections necessary to handle odd numbers
1457  size_t halfoff = ((double) npix)/2.0 + 0.5;
1458  size_t oneoff = 0;
1459  if(halfoff > npix/2) oneoff = 0;
1460 
1461  #ifndef XRIF_NO_OMP
1462  #pragma omp parallel if (handle->omp_parallel > 0)
1463  {
1464  #pragma omp for
1465  #endif
1466  for(size_t pix = 0; pix < npix; ++pix)
1467  {
1468  /* This block of commented code is left in to document the algorithm implemented in the lookup table.
1469  * And maybe we'll implement some defines to avoid lookup tables . . .
1470  */
1471 
1472  /*
1473  int_fast16_t s = raw_buffer[pix]; //Get the first 2 bytes
1474  int_fast16_t sbit = (s < 0); //and the signbit
1475 
1476  s *= (1-2*sbit); //make it positive
1477 
1478  uint16_t us = ( (s) << 1) | sbit; //This moves the sign bit
1479 
1480  reordered_buffer[pix] = ((char *)(&us))[0]; //store first byte, which includes the sign bit?
1481 
1482  // Note: A pre-calculated table look-up for just nibble values produced slightly slower code.
1483  uint16_t nib1, nib2;
1484 
1485  if(pix % 2 == 0)
1486  {
1487  nib1 = ((unsigned char *)(&us))[1] << 4; //Move low 4 to high 4
1488  nib2 = ((unsigned char *)(&us))[1] & 240; //Select the high 4
1489  }
1490  else
1491  {
1492  nib1 = (((unsigned char *)(&us))[1] & 15); //Select the low 4
1493  nib2 = ((unsigned char *)(&us))[1] >> 4; //Move the high 4 to the low 4
1494  }
1495 
1496  reordered_buffer2[pix/2] |= nib1;
1497  reordered_buffer2[pix/2 + oneoff + halfoff] |= nib2;
1498  */
1499  /*
1500  Here we use a lookup table calculated according to the above algorithm:
1501  */
1502 
1503  const unsigned char * bsn = &bitshift_and_nibbles[ ((uint16_t) raw_buffer[pix]) * 6 + (pix&1)*3];
1504  reordered_buffer[pix] = (char) bsn[0];
1505  reordered_buffer2[pix/2] += bsn[1];
1506  reordered_buffer2[pix/2 + oneoff + halfoff] += bsn[2];
1507 
1508  }
1509  #ifndef XRIF_NO_OMP
1510  }
1511  #endif
1512 
1513  return XRIF_NOERROR;
1514 }
1515 
1516 ///\todo xrif_reorder_bitpack needs a size check
1518 {
1519  //The lookup tables (static arrays)
1520  #include "bit_to_position.inc"
1521  #include "set_bits.inc"
1522 
1523  size_t one_frame, npix;
1524 
1525  //If it's pixel, we reorder the first frame too.
1526  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1527  {
1528  one_frame = 0;
1529  npix = handle->width * handle->height * handle->depth * handle->frames;
1530  }
1531  else //Otherwise we don't include the first frame in the re-ordering
1532  {
1533  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1534  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1535  }
1536 
1537  for(size_t pix=0; pix < one_frame; ++pix)
1538  {
1539  handle->reordered_buffer[pix] = handle->raw_buffer[pix];
1540  }
1541 
1542  int16_t * raw_buffer = (int16_t *) (handle->raw_buffer + one_frame);
1543  uint16_t * reordered_buffer = (uint16_t *) (handle->reordered_buffer + one_frame);
1544 
1545  memset( (char *) reordered_buffer, 0, handle->reordered_buffer_size - one_frame);
1546 
1547  size_t stride = (handle->reordered_buffer_size - one_frame)/16/2; //stride in 16-bit pixels, not bytes
1548 
1549  #ifndef XRIF_NO_OMP
1550  #pragma omp parallel if (handle->omp_parallel > 0)
1551  {
1552  #pragma omp for
1553  #endif
1554 
1555 
1556  for(size_t pix = 0; pix<npix; ++pix)
1557  {
1558  size_t sbyte = pix/16; //This is the starting byte for this pixel
1559  int_fast8_t bit = pix % 16; //This is the bit position for this pixel
1560 
1561 
1562  //--- Reordering sign bit [left in to document]
1563  //int16_t s = raw_buffer[pix];
1564  //int8_t sbit = (s < 0);
1565  //s *= (1-2*sbit); //make positive
1566  //uint16_t us = ( (s) << 1) | sbit; //shift by 1, putting sign bit in highest entropy spot
1567 
1568  //--- Simpler way to reorder, this is equivalent to above
1569  int8_t sbit = (raw_buffer[pix] < 0);
1570  uint16_t us = 2*raw_buffer[pix]*(1-2*sbit)+sbit;
1571 
1572 
1573  //---- This is the basic algorithm, without lookup tables:
1574  /*
1575  for(int b=0; b < 16; ++b)
1576  {
1577  reordered_buffer[sbyte + b*stride] += (((us >> b) & 1) << bit);
1578  }
1579  */
1580 
1581  //---- A full lookup table version
1582  //Attempt with lookup table is slower, leaving this in to document this, possibly for future defines:
1583  //uint16_t us = left_shift_one[*((uint16_t *) &raw_buffer[pix])];
1584 
1585  //---- A faster lookup table version:
1586  size_t sbyte8 = sbyte + 8*stride;
1587  size_t st0 = ((unsigned char *) &us)[0]*16*8 + bit*8;
1588  size_t st1 = ((unsigned char *) &us)[1]*16*8 + bit*8;
1589 
1590  for(int_fast8_t b = 0; b < 8; ++b)
1591  {
1592  reordered_buffer[sbyte + b*stride] += bit_to_position[st0 + b] ;
1593  }
1594  if(((unsigned char *) &us)[1] == 0) continue;
1595 
1596  //Get the number of set bits, and for this second byte we only process those bits.
1597  unsigned char nbits2 = set_bits[((unsigned char *) &us)[1]*9];
1598  const unsigned char* bits2 = &set_bits[((unsigned char *) &us)[1]*9 + 1];
1599  for(int_fast8_t b = 0; b < nbits2; ++b)
1600  {
1601  reordered_buffer[sbyte8 + bits2[b]*stride] += bit_to_position[st1 + bits2[b]];
1602  }
1603 
1604 
1605 
1606  }
1607  #ifndef XRIF_NO_OMP
1608  }
1609  #endif
1610 
1611  return XRIF_NOERROR;
1612 }
1613 
1614 
1615 /// Perform no un-re-ordering, simply copy reordered to raw.
1617 {
1618  size_t npix = handle->width * handle->height * handle->depth * handle->frames;
1619 
1620  if( handle == NULL)
1621  {
1622  return XRIF_ERROR_NULLPTR;
1623  }
1624 
1625  if( handle->raw_buffer_size < npix*handle->data_size )
1626  {
1628  }
1629 
1630  if( handle->reordered_buffer_size < npix*handle->data_size )
1631  {
1633  }
1634 
1635  memcpy(handle->raw_buffer, handle->reordered_buffer, npix*handle->data_size);
1636 
1637  //Zero the rest of the raw buffer.
1638  if(handle->raw_buffer_size > npix*handle->data_size)
1639  {
1640  memset(handle->raw_buffer + npix*handle->data_size, 0, handle->raw_buffer_size-npix*handle->data_size);
1641  }
1642 
1643  return XRIF_NOERROR;
1644 }
1645 
1646 //--------------------------------------------------------------------
1647 // bytepack unreodering
1648 //--------------------------------------------------------------------
1649 
1650 //Dispatch bytepack unreordering according to type
1652 {
1653  if( handle == NULL)
1654  {
1655  XRIF_ERROR_PRINT("xrif_unreorder_bytepack", "can not use a null pointer");
1656  return XRIF_ERROR_NULLPTR;
1657  }
1658 
1659  if(handle->type_code == XRIF_TYPECODE_INT16 || handle->type_code == XRIF_TYPECODE_UINT16)
1660  {
1661  return xrif_unreorder_bytepack_sint16(handle);
1662  }
1663  else if(handle->type_code == XRIF_TYPECODE_INT32 || handle->type_code == XRIF_TYPECODE_UINT32)
1664  {
1665  XRIF_ERROR_PRINT("xrif_unreorder_bytepack", "bytepack unreordering not implemented for 32 bit ints");
1666  return XRIF_ERROR_NOTIMPL;
1667  }
1668  else if(handle->type_code == XRIF_TYPECODE_INT64 || handle->type_code == XRIF_TYPECODE_UINT64)
1669  {
1670  XRIF_ERROR_PRINT("xrif_unreorder_bytepack", "bytepack unreordering not implemented for 64 bit ints");
1671  return XRIF_ERROR_NOTIMPL;
1672  }
1673  else
1674  {
1675  XRIF_ERROR_PRINT("xrif_unreorder_bytepack", "bytepack unreordering not implemented for type");
1676  return XRIF_ERROR_NOTIMPL;
1677  }
1678 
1679 }
1680 
1681 //Unreorder bytepack for signed 16 bit ints
1683 {
1684 
1685 
1686  size_t one_frame, npix;
1687 
1688  if( handle == NULL)
1689  {
1690  XRIF_ERROR_PRINT("xrif_unreorder_bytepack_sint16", "can not use a null pointer");
1691  return XRIF_ERROR_NULLPTR;
1692  }
1693 
1694  //If it's pixel, we reorder the first frame too.
1695  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1696  {
1697  one_frame = 0;
1698  npix = handle->width * handle->height * handle->depth * handle->frames;
1699  }
1700  else //Otherwise we don't include the first frame in the re-ordering
1701  {
1702  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1703  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1704  }
1705 
1706  char * raw_buffer = handle->raw_buffer + one_frame;
1707  char * reordered_buffer = handle->reordered_buffer + one_frame;
1708 
1709  for(size_t pix=0; pix<one_frame; ++pix)
1710  {
1711  handle->raw_buffer[pix] = handle->reordered_buffer[pix];
1712  }
1713 
1714  #ifndef XRIF_NO_OMP
1715  #pragma omp parallel if (handle->omp_parallel > 0)
1716  {
1717  #pragma omp for
1718  #endif
1719  for(size_t pix = 0; pix < npix; ++pix)
1720  {
1721  int_fast8_t x2 = reordered_buffer[pix];
1722  int_fast8_t x1 = reordered_buffer[npix+pix];
1723 
1724  if(x2 < 0)
1725  {
1726  if(x1 == -1) x1 = 0;
1727  else if(x1 == 0) x1 = -1;
1728  }
1729 
1730  raw_buffer[2*pix] = x2;
1731  raw_buffer[2*pix+1] = x1;
1732 
1733  }
1734 
1735  #ifndef XRIF_NO_OMP
1736  }
1737  #endif
1738 
1739  return XRIF_NOERROR;
1740 }
1741 
1743 {
1744  size_t one_frame, npix;
1745 
1746  //If it's pixel, we reorder the first frame too.
1747  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1748  {
1749  one_frame = 0;
1750  npix = handle->width * handle->height * handle->depth * handle->frames;
1751  }
1752  else //Otherwise we don't include the first frame in the re-ordering
1753  {
1754  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1755  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1756  }
1757 
1758  int16_t * raw_buffer = (int16_t*)(handle->raw_buffer + one_frame);
1759  unsigned char * reordered_buffer = (unsigned char *) handle->reordered_buffer + one_frame;
1760  unsigned char * reordered_buffer2 = (unsigned char*) reordered_buffer + npix;
1761 
1762  for(size_t pix=0; pix<one_frame; ++pix)
1763  {
1764  handle->raw_buffer[pix] = handle->reordered_buffer[pix];
1765  }
1766 
1767  size_t halfoff = ((double) npix)/2 + 0.5;
1768  size_t oneoff = 0;
1769  if(halfoff > npix/2) oneoff = 0;
1770 
1771  #ifndef XRIF_NO_OMP
1772  #pragma omp parallel if (handle->omp_parallel > 0)
1773  {
1774  #pragma omp for
1775  #endif
1776  for(size_t pix = 0; pix < npix; ++pix)
1777  {
1778  uint16_t byte1 = 0;
1779  byte1 = reordered_buffer[pix];
1780 
1781  uint16_t nib1 =0;
1782  uint16_t nib2 = 0;
1783  if(pix % 2 == 0)
1784  {
1785  nib1 |= ((reordered_buffer2[pix/2+oneoff])) >> 4;
1786  nib2 |= reordered_buffer2[pix/2+oneoff + halfoff] & 240;
1787  }
1788  else
1789  {
1790  nib1 |= reordered_buffer2[pix/2] & 15;
1791  nib2 |= (reordered_buffer2[pix/2 + oneoff + halfoff] & 15) << 4;
1792  }
1793 
1794  byte1 |= (nib1 << 8);
1795  byte1 |= (nib2 << 8);
1796 
1797 
1798  unsigned int sbit = (byte1 & 1);
1799 
1800  unsigned int s = (byte1 >> 1);
1801 
1802 
1803  if(sbit == 1 && s == 0)
1804  {
1805  raw_buffer[pix] = -32768;
1806  }
1807  else
1808  {
1809  raw_buffer[pix] = s*(1-2*sbit);
1810  }
1811  }
1812 
1813  #ifndef XRIF_NO_OMP
1814  }
1815  #endif
1816 
1817  return XRIF_NOERROR;
1818 }
1819 
1821 {
1822  size_t one_frame, npix;
1823 
1824  //If it's pixel, we reorder the first frame too.
1825  if(handle->difference_method == XRIF_DIFFERENCE_PIXEL)
1826  {
1827  one_frame = 0;
1828  npix = handle->width * handle->height * handle->depth * handle->frames;
1829  }
1830  else //Otherwise we don't include the first frame in the re-ordering
1831  {
1832  one_frame = handle->width*handle->height* handle->depth *handle->data_size; //bytes
1833  npix = handle->width * handle->height * handle->depth * (handle->frames-1); //pixels not bytes
1834  }
1835 
1836  for(size_t pix=0; pix< one_frame; ++pix)
1837  {
1838  handle->raw_buffer[pix] = handle->reordered_buffer[pix];
1839  }
1840 
1841  int16_t * raw_buffer = (int16_t *) (handle->raw_buffer + one_frame);
1842  uint16_t * reordered_buffer = (uint16_t *) (handle->reordered_buffer + one_frame);
1843 
1844  memset(raw_buffer, 0, npix*2);
1845 
1846  //size_t stride = npix/16;
1847  size_t stride = (handle->reordered_buffer_size - one_frame)/16/2;
1848  //printf("strides: %ld %ld\n", npix/16, stride);
1849 
1850  #ifndef XRIF_NO_OMP
1851  #pragma omp parallel if (handle->omp_parallel > 0)
1852  {
1853  #pragma omp for
1854  #endif
1855  for(size_t pix = 0; pix<npix; ++pix)
1856  {
1857 
1858  size_t sbyte = pix/16;
1859  size_t bit = pix % 16;
1860 
1861  char sbit = (reordered_buffer[sbyte] >> bit) & 1;
1862 
1863  for(int_fast8_t b=1; b<16;++b)
1864  {
1865  raw_buffer[pix] |= ((reordered_buffer[sbyte + b*stride] >> bit) & 1) << (b-1);
1866  }
1867 
1868  //Check if sign change needed
1869  if(sbit == 1)
1870  {
1871  //Check for -0, which is actually -32768
1872  if(raw_buffer[pix] == 0) raw_buffer[pix] = -32768;
1873  else raw_buffer[pix] *= -1;
1874  }
1875 
1876 
1877  }
1878 
1879  #ifndef XRIF_NO_OMP
1880  }
1881  #endif
1882 
1883  return XRIF_NOERROR;
1884 }
1885 
1886 
1887 
1889 {
1890  int method = handle->compress_method;
1891 
1892  if(method == 0) method = XRIF_COMPRESS_DEFAULT;
1893 
1894  switch( method )
1895  {
1896  case XRIF_COMPRESS_NONE:
1897  return xrif_compress_none(handle);
1898  case XRIF_COMPRESS_LZ4:
1899  return xrif_compress_lz4(handle);
1900  default:
1901  return XRIF_ERROR_NOTIMPL;
1902  }
1903 
1904 }
1905 
1907 {
1908  int method = handle->compress_method;
1909 
1910  if(method == 0) method = XRIF_COMPRESS_DEFAULT;
1911 
1912  switch( method )
1913  {
1914  case XRIF_COMPRESS_NONE:
1915  return xrif_decompress_none(handle);
1916  case XRIF_COMPRESS_LZ4:
1917  return xrif_decompress_lz4(handle);
1918  default:
1919  fprintf(stderr, "xrif_decompress: unknown compression method (%d)\n", method);
1920  return XRIF_ERROR_NOTIMPL;
1921  }
1922 
1923 }
1924 
1925 ///\todo xrif_compress_none needs size checks
1927 {
1928  char *compressed_buffer;
1929  size_t compressed_size;
1930 
1931  if(handle->compress_on_raw)
1932  {
1933  compressed_buffer = handle->raw_buffer;
1934  compressed_size = handle->raw_buffer_size;
1935  }
1936  else
1937  {
1938  compressed_buffer = handle->compressed_buffer;
1939  compressed_size = handle->compressed_buffer_size;
1940  }
1941 
1942  //Make sure there is enough space
1943  if( compressed_size < handle->reordered_buffer_size )
1944  {
1946  }
1947 
1948  //Zero extra pixels
1949  if(compressed_size > handle->reordered_buffer_size)
1950  {
1951  ///\todo this can be just the xtra pixels
1952  memset(compressed_buffer, 0, compressed_size);
1953  }
1954 
1955  handle->compressed_size = handle->reordered_buffer_size;
1956 
1957  memcpy( compressed_buffer, handle->reordered_buffer, handle->compressed_size);
1958 
1959  return XRIF_NOERROR;
1960 }
1961 
1963 {
1964  char *compressed_buffer;
1965 
1966  if(handle->compress_on_raw)
1967  {
1968  compressed_buffer = handle->raw_buffer;
1969  }
1970  else
1971  {
1972  compressed_buffer = handle->compressed_buffer;
1973  }
1974 
1975  //The reordered buffer must be big enough to old the compressed data
1976  if(handle->reordered_buffer_size < handle->compressed_size)
1977  {
1978  fprintf(stderr, "xrif_decompress_none: reordered_buffer is too small (%ld < %ld).\n", handle->reordered_buffer_size, handle->compressed_size);
1980  }
1981 
1982  //If the reordered buffer is larger than needed to hold the compressed buffer, set extras to 0
1983  if(handle->reordered_buffer_size > handle->compressed_size)
1984  {
1985  ///\todo this can be just the extra bytes
1986  memset(handle->reordered_buffer, 0, handle->reordered_buffer_size);
1987  }
1988 
1989  //Now it's just a straight copy from compressed to reordered buffer.
1990  memcpy( handle->reordered_buffer, compressed_buffer, handle->compressed_size);
1991 
1992  return XRIF_NOERROR;
1993 }
1994 
1995 ///\todo xrif_compress_lz4 needs size checks
1997 {
1998  char *compressed_buffer;
1999  size_t compressed_size;
2000 
2001  if(handle->compress_on_raw)
2002  {
2003  compressed_buffer = handle->raw_buffer;
2004  compressed_size = handle->raw_buffer_size;
2005  }
2006  else
2007  {
2008  compressed_buffer = handle->compressed_buffer;
2009  compressed_size = handle->compressed_buffer_size;
2010  }
2011 
2012  //LZ4 only takes ints for sizes
2013  int srcSize = xrif_min_reordered_size(handle); //This tells us how much memory is actually used by the reordering algorithm.
2014 
2015  handle->compressed_size = LZ4_compress_fast ( handle->reordered_buffer, compressed_buffer, srcSize, compressed_size, handle->lz4_acceleration);
2016 
2017  if(handle->compressed_size == 0 )
2018  {
2019  fprintf(stderr, "xrif_compress_lz4: compression failed.\n");
2021  }
2022 
2023 
2024  return XRIF_NOERROR;
2025 }
2026 
2028 {
2029  if(handle == NULL)
2030  {
2031  XRIF_ERROR_PRINT("xrif_decompress_lz4", "can not use a null pointer");
2032  return XRIF_ERROR_NULLPTR;
2033  }
2034 
2035  char *compressed_buffer;
2036 
2037  if(handle->compress_on_raw)
2038  {
2039  compressed_buffer = handle->raw_buffer;
2040  }
2041  else
2042  {
2043  compressed_buffer = handle->compressed_buffer;
2044  }
2045 
2046  int size_decomp = LZ4_decompress_safe (compressed_buffer, handle->reordered_buffer, handle->compressed_size, handle->reordered_buffer_size);
2047 
2048  if(size_decomp < 0)
2049  {
2050  XRIF_ERROR_PRINT("xrif_decompress_lz4", "error in LZ4_decompress_safe");
2051  return (XRIF_ERROR_LIBERR + size_decomp);
2052  }
2053 
2054  //Make sure we have the correct amount of data
2055  if(xrif_min_reordered_size(handle) != size_decomp)
2056  {
2057  XRIF_ERROR_PRINT("xrif_decompress_lz4", "size mismatch after decompression.");
2058  return XRIF_ERROR_INVALID_SIZE;
2059  }
2060 
2061  return XRIF_NOERROR;
2062 }
2063 
2065 {
2066  return ((double)handle->compressed_size)/((double)handle->raw_size);
2067 }
2068 
2069 double xrif_encode_time( xrif_t handle )
2070 {
2071  return xrif_ts_difference( &handle->ts_compress_done, &handle->ts_difference_start);
2072 }
2073 
2074 double xrif_encode_rate( xrif_t handle )
2075 {
2076  return ((double) handle->raw_size) /xrif_encode_time(handle);
2077 }
2078 
2080 {
2081  return xrif_ts_difference( &handle->ts_reorder_start, &handle->ts_difference_start);
2082 }
2083 
2085 {
2086  return ((double) handle->raw_size) / xrif_difference_time(handle);
2087 }
2088 
2089 double xrif_reorder_time( xrif_t handle )
2090 {
2091  return xrif_ts_difference( &handle->ts_compress_start, &handle->ts_reorder_start);
2092 }
2093 
2094 double xrif_reorder_rate( xrif_t handle )
2095 {
2096  return ((double) handle->raw_size) /xrif_reorder_time(handle);
2097 }
2098 
2099 double xrif_compress_time( xrif_t handle )
2100 {
2101  return xrif_ts_difference( &handle->ts_compress_done, &handle->ts_compress_start);
2102 }
2103 
2104 double xrif_compress_rate( xrif_t handle )
2105 {
2106  return ((double) handle->raw_size) /xrif_compress_time(handle);
2107 }
2108 
2109 //-
2110 
2111 double xrif_decode_time( xrif_t handle )
2112 {
2113  return xrif_ts_difference( &handle->ts_undifference_done, &handle->ts_decompress_start);
2114 }
2115 
2116 double xrif_decode_rate( xrif_t handle )
2117 {
2118  return ((double) handle->raw_size) /xrif_decode_time(handle);
2119 }
2120 
2122 {
2124 }
2125 
2127 {
2128  return ((double) handle->raw_size) / xrif_undifference_time(handle);
2129 }
2130 
2131 double xrif_unreorder_time( xrif_t handle )
2132 {
2133  return xrif_ts_difference( &handle->ts_undifference_start, &handle->ts_unreorder_start);
2134 }
2135 
2136 double xrif_unreorder_rate( xrif_t handle )
2137 {
2138  return ((double) handle->raw_size) /xrif_unreorder_time(handle);
2139 }
2140 
2142 {
2143  return xrif_ts_difference( &handle->ts_unreorder_start, &handle->ts_decompress_start);
2144 }
2145 
2147 {
2148  return ((double) handle->raw_size) /xrif_decompress_time(handle);
2149 }
2150 size_t xrif_typesize( xrif_typecode_t type_code)
2151 {
2152  switch( type_code )
2153  {
2154  case XRIF_TYPECODE_UINT8:
2155  return sizeof(uint8_t);
2156  case XRIF_TYPECODE_INT8:
2157  return sizeof(int8_t);
2158  case XRIF_TYPECODE_UINT16:
2159  return sizeof(uint16_t);
2160  case XRIF_TYPECODE_INT16:
2161  return sizeof(int16_t);
2162  case XRIF_TYPECODE_UINT32:
2163  return sizeof(uint32_t);
2164  case XRIF_TYPECODE_INT32:
2165  return sizeof(int32_t);
2166  case XRIF_TYPECODE_UINT64:
2167  return sizeof(uint64_t);
2168  case XRIF_TYPECODE_INT64:
2169  return sizeof(int64_t);
2170  case XRIF_TYPECODE_HALF:
2171  return sizeof(uint16_t);
2172  case XRIF_TYPECODE_FLOAT:
2173  return sizeof(float);
2174  case XRIF_TYPECODE_DOUBLE:
2175  return sizeof(double);
2177  return sizeof(float[2]);
2179  return sizeof(double[2]);
2180  default:
2181  return 0;
2182  }
2183 }
2184 
2185 double xrif_ts_difference( struct timespec * ts1,
2186  struct timespec * ts0
2187  )
2188 {
2189  return ((double)ts1->tv_sec) + ((double)ts1->tv_nsec)/1e9 - ((double)ts0->tv_sec) - ((double)ts0->tv_nsec)/1e9;
2190 }
2191 
2192 const char * xrif_difference_method_string( int diff_method )
2193 {
2194  switch(diff_method)
2195  {
2196  case XRIF_DIFFERENCE_NONE:
2197  return "none";
2198  case XRIF_DIFFERENCE_PREVIOUS:
2199  return "previous";
2200  case XRIF_DIFFERENCE_FIRST:
2201  return "first";
2202  default:
2203  return "unknown";
2204  }
2205 }
2206 
2207 const char * xrif_reorder_method_string( int reorder_method )
2208 {
2209  switch(reorder_method)
2210  {
2211  case XRIF_REORDER_NONE:
2212  return "none";
2213  case XRIF_REORDER_BYTEPACK:
2214  return "bytepack";
2215  case XRIF_REORDER_BYTEPACK_RENIBBLE:
2216  return "bytepack w/ renibble";
2217  case XRIF_REORDER_BITPACK:
2218  return "bitpack";
2219  default:
2220  return "unknown";
2221  }
2222 }
2223 
2224 const char * xrif_compress_method_string( int compress_method )
2225 {
2226  switch(compress_method)
2227  {
2228  case XRIF_COMPRESS_NONE:
2229  return "none";
2230  case XRIF_COMPRESS_LZ4:
2231  return "LZ4";
2232  default:
2233  return "unknown";
2234  }
2235 }
xrif_frames
xrif_dimension_t xrif_frames(xrif_t handle)
Get the current number of frames of the configured handle.
Definition: xrif.c:834
xrif_encode_rate
double xrif_encode_rate(xrif_t handle)
Calculate the encode rate in bytes/sec.
Definition: xrif.c:2074
xrif_handle::compression_ratio
double compression_ratio
The compression ratio, calculated as output-size/input-size.
Definition: xrif.h:360
xrif_set_compressed
xrif_error_t xrif_set_compressed(xrif_t handle, void *compressed, size_t size)
Set the compressed data buffer to a pre-allocated pointer.
Definition: xrif.c:715
xrif_handle::compress_time
double compress_time
Time in seconds taken to compress the data.
Definition: xrif.h:367
XRIF_ERROR_INVALID_SIZE
#define XRIF_ERROR_INVALID_SIZE
Return code indicating that an invalid size was passed.
Definition: xrif.h:169
XRIF_TYPECODE_INT32
#define XRIF_TYPECODE_INT32
32-bit signed integer
Definition: xrif.h:221
XRIF_ERROR_NULLPTR
#define XRIF_ERROR_NULLPTR
Return code indicating that a NULL pointer was passed.
Definition: xrif.h:163
xrif_handle::width
xrif_dimension_t width
The width of a single image, in pixels.
Definition: xrif.h:308
xrif_handle::reordered_buffer
char * reordered_buffer
The reordered buffer pointer, contains the reordered data.
Definition: xrif.h:343
xrif_handle::difference_method
int difference_method
The difference method to use.
Definition: xrif.h:320
xrif_handle::ts_undifference_start
struct timespec ts_undifference_start
Timespec used to mark the beginning of undifferencing, which is the end of unreordering.
Definition: xrif.h:377
XRIF_TYPECODE_DOUBLE
#define XRIF_TYPECODE_DOUBLE
IEEE 754 double-precision binary floating-point format: binary64.
Definition: xrif.h:231
xrif_read_header
xrif_error_t xrif_read_header(xrif_t handle, uint32_t *header_size, char *header)
Configure an xrif handle by reading a xrif protocol header.
Definition: xrif.c:901
xrif_undifference_first
xrif_error_t xrif_undifference_first(xrif_t handle)
Undifference the images using the first image as a reference.
Definition: xrif_difference_first.c:386
xrif_difference_previous
xrif_error_t xrif_difference_previous(xrif_t handle)
Difference the images using the previous image as a reference.
Definition: xrif_difference_previous.c:216
xrif_encode_time
double xrif_encode_time(xrif_t handle)
Calculate the time in seconds taken to encode the data.
Definition: xrif.c:2069
xrif_allocate_reordered
xrif_error_t xrif_allocate_reordered(xrif_t handle)
Allocate the reordered buffer based on the already set stream dimensions.
Definition: xrif.c:673
xrif_handle::ts_compress_start
struct timespec ts_compress_start
Timespec used to mark the beginning of compression, which is the end of reordering.
Definition: xrif.h:372
xrif_handle::ts_decompress_start
struct timespec ts_decompress_start
Timespec used to mark the beginning of decompression, which is also the beginning of decoding.
Definition: xrif.h:375
xrif_ts_difference
double xrif_ts_difference(struct timespec *ts1, struct timespec *ts0)
Calculate the difference between two timespecs.
Definition: xrif.c:2185
xrif_decompress_time
double xrif_decompress_time(xrif_t handle)
Calculate the time in seconds taken to decompress the differenced and reordered data.
Definition: xrif.c:2141
xrif_handle::compress_method
int compress_method
The compression method used.
Definition: xrif.h:324
xrif_handle::omp_numthreads
int omp_numthreads
Definition: xrif.h:331
xrif_min_raw_size
size_t xrif_min_raw_size(xrif_t handle)
Calculate the minimum size of the raw buffer.
Definition: xrif.c:462
xrif_difference_rate
double xrif_difference_rate(xrif_t handle)
Calculate the differencing rate in bytes/sec.
Definition: xrif.c:2084
xrif_typecode_t
uint8_t xrif_typecode_t
The type used for storing the ImageStreamIO data type code.
Definition: xrif.h:208
xrif_unreorder_time
double xrif_unreorder_time(xrif_t handle)
Calculate the time in seconds taken to unreorder the data.
Definition: xrif.c:2131
xrif_t
xrif_handle * xrif_t
The xrif handle pointer type. This provides the main interface to the xrif library.
Definition: xrif.h:385
xrif_handle::compressed_buffer
char * compressed_buffer
The compressed buffer pointer, contains the compressed data.
Definition: xrif.h:349
XRIF_TYPECODE_INT16
#define XRIF_TYPECODE_INT16
16-bit signed integer
Definition: xrif.h:217
xrif_handle::reorder_method
int reorder_method
The method to use for bit reordering.
Definition: xrif.h:322
xrif_depth
xrif_dimension_t xrif_depth(xrif_t handle)
Get the current depth of the configured handle.
Definition: xrif.c:823
xrif_min_compressed_size
size_t xrif_min_compressed_size(xrif_t handle)
Calculate the minimum size of the compressed buffer.
Definition: xrif.c:521
xrif_handle::omp_parallel
int omp_parallel
Definition: xrif.h:328
xrif_reorder_bytepack_renibble
xrif_error_t xrif_reorder_bytepack_renibble(xrif_t handle)
Definition: xrif.c:1409
xrif_allocate_raw
xrif_error_t xrif_allocate_raw(xrif_t handle)
Allocate the raw buffer based on the already set stream dimensions.
Definition: xrif.c:584
xrif_handle::ts_reorder_start
struct timespec ts_reorder_start
Timespec used to mark the beginning of reordering, which is the end of differencing.
Definition: xrif.h:371
xrif_handle::lz4_acceleration
int lz4_acceleration
LZ4 acceleration parameter, >=1, higher is faster with less comporession. Default is 1.
Definition: xrif.h:326
xrif_set_compress_method
xrif_error_t xrif_set_compress_method(xrif_t handle, int compress_method)
Set the compress method.
Definition: xrif.c:408
XRIF_TYPECODE_UINT64
#define XRIF_TYPECODE_UINT64
64-bit unsigned integer
Definition: xrif.h:223
xrif_handle
The xrif library configuration structure, organizing various parameters used by the functions.
Definition: xrif.h:306
xrif_handle::frames
xrif_dimension_t frames
The number of frames in the stream.
Definition: xrif.h:311
xrif_difference_method_string
const char * xrif_difference_method_string(int diff_method)
Get a string describing the difference method.
Definition: xrif.c:2192
xrif_set_raw
xrif_error_t xrif_set_raw(xrif_t handle, void *raw, size_t size)
Set the raw data buffer to a pre-allocated pointer.
Definition: xrif.c:538
XRIF_ERROR_BADHEADER
#define XRIF_ERROR_BADHEADER
Return code indicating that the header is bad.
Definition: xrif.h:187
xrif_set_lz4_acceleration
xrif_error_t xrif_set_lz4_acceleration(xrif_t handle, int32_t lz4_accel)
Set the LZ4 acceleration parameter.
Definition: xrif.c:432
xrif_reorder_bytepack_sint16
xrif_error_t xrif_reorder_bytepack_sint16(xrif_t handle)
Perform bytepack reodering for signed 16 bit ints.
Definition: xrif.c:1336
xrif_undifference_pixel
xrif_error_t xrif_undifference_pixel(xrif_t handle)
Undifference the images using the previous pixel as a reference.
Definition: xrif_difference_pixel.c:413
XRIF_ERROR_PRINT
#define XRIF_ERROR_PRINT(function, msg)
Standard error report.
Definition: xrif.h:196
xrif_handle::calc_performance
unsigned char calc_performance
Flag (true/false) controlling whether performance metrics are calculated. Default is true.
Definition: xrif.h:358
xrif_decompress_lz4
xrif_error_t xrif_decompress_lz4(xrif_t handle)
Definition: xrif.c:2027
xrif_reorder_method_string
const char * xrif_reorder_method_string(int reorder_method)
Get a string describing the reordering method.
Definition: xrif.c:2207
XRIF_ERROR_NOT_SETUP
#define XRIF_ERROR_NOT_SETUP
Return code indicating that the handle was not setup.
Definition: xrif.h:166
XRIF_TYPECODE_COMPLEX_DOUBLE
#define XRIF_TYPECODE_COMPLEX_DOUBLE
complex double
Definition: xrif.h:235
xrif_write_header
xrif_error_t xrif_write_header(char *header, xrif_t handle)
Populate a header buffer with the xrif protocol details.
Definition: xrif.c:846
XRIF_ERROR_BADARG
#define XRIF_ERROR_BADARG
Return code indicating that a bad argument was passed.
Definition: xrif.h:184
xrif_handle::reordered_buffer_size
size_t reordered_buffer_size
Definition: xrif.h:344
xrif_reorder_time
double xrif_reorder_time(xrif_t handle)
Calculate the time in seconds taken to reorder the data.
Definition: xrif.c:2089
xrif_handle::reorder_time
double reorder_time
Time in seconds taken to reorder the data.
Definition: xrif.h:365
xrif_new
xrif_error_t xrif_new(xrif_t *handle_ptr)
Allocate a handle and initialize it.
Definition: xrif.c:107
xrif_decompress_rate
double xrif_decompress_rate(xrif_t handle)
Calculate the decompression rate in bytes/sec.
Definition: xrif.c:2146
xrif_compress_rate
double xrif_compress_rate(xrif_t handle)
Calculate the compression rate in bytes/sec.
Definition: xrif.c:2104
xrif_unreorder_none
xrif_error_t xrif_unreorder_none(xrif_t handle)
Perform no un-re-ordering, simply copy reordered to raw.
Definition: xrif.c:1616
xrif_handle::height
xrif_dimension_t height
The height of a single image, in pixels.
Definition: xrif.h:309
XRIF_TYPECODE_UINT32
#define XRIF_TYPECODE_UINT32
32-bit unsigned integer
Definition: xrif.h:219
xrif_undifference_rate
double xrif_undifference_rate(xrif_t handle)
Calculate the undifferencing rate in bytes/sec.
Definition: xrif.c:2126
xrif_handle::own_reordered
unsigned char own_reordered
Flag (true/false) indicating whether the reordered_buffer pointer is managed by this handle.
Definition: xrif.h:342
xrif_undifference_time
double xrif_undifference_time(xrif_t handle)
Calculate the time in seconds taken to undifference the data.
Definition: xrif.c:2121
xrif_allocate_compressed
xrif_error_t xrif_allocate_compressed(xrif_t handle)
Allocate the compressed buffer based on the already set stream dimensions.
Definition: xrif.c:760
XRIF_ERROR_WRONGVERSION
#define XRIF_ERROR_WRONGVERSION
Return code indicating that a wrong version was specified.
Definition: xrif.h:190
xrif_width
xrif_dimension_t xrif_width(xrif_t handle)
Get the current width of the configured handle.
Definition: xrif.c:801
xrif_unreorder_bytepack_renibble
xrif_error_t xrif_unreorder_bytepack_renibble(xrif_t handle)
Definition: xrif.c:1742
xrif_unreorder_rate
double xrif_unreorder_rate(xrif_t handle)
Calculate the unreordering rate in bytes/sec.
Definition: xrif.c:2136
xrif_set_reordered
xrif_error_t xrif_set_reordered(xrif_t handle, void *reordered, size_t size)
Set the rordered (working) data buffer to a pre-allocated pointer.
Definition: xrif.c:627
xrif_compress_none
xrif_error_t xrif_compress_none(xrif_t handle)
Definition: xrif.c:1926
xrif_decode_rate
double xrif_decode_rate(xrif_t handle)
Calculate the decode rate in bytes/sec.
Definition: xrif.c:2116
xrif_set_difference_method
xrif_error_t xrif_set_difference_method(xrif_t handle, int difference_method)
Set the difference method.
Definition: xrif.c:355
xrif_handle::compress_on_raw
unsigned char compress_on_raw
Flag (true/false) indicating whether the raw buffer is used for compression. Default on initializeati...
Definition: xrif.h:334
xrif_error_t
int xrif_error_t
The error reporting type.
Definition: xrif.h:157
xrif_difference
xrif_error_t xrif_difference(xrif_t handle)
Difference the image(s)
Definition: xrif.c:1102
XRIF_TYPECODE_UINT8
#define XRIF_TYPECODE_UINT8
8-bit unsigned integer
Definition: xrif.h:211
xrif_compress_lz4
xrif_error_t xrif_compress_lz4(xrif_t handle)
Definition: xrif.c:1996
XRIF_TYPECODE_INT8
#define XRIF_TYPECODE_INT8
8-bit signed integer
Definition: xrif.h:213
xrif_compress_time
double xrif_compress_time(xrif_t handle)
Calculate the time in seconds taken to compress the differenced and reordered data.
Definition: xrif.c:2099
xrif_set_size
xrif_error_t xrif_set_size(xrif_t handle, xrif_dimension_t w, xrif_dimension_t h, xrif_dimension_t d, xrif_dimension_t f, xrif_typecode_t c)
Set the basic parameters of an xrif handle.
Definition: xrif.c:128
XRIF_ERROR_MALLOC
#define XRIF_ERROR_MALLOC
Return code indicating a malloc failure.
Definition: xrif.h:178
XRIF_TYPECODE_FLOAT
#define XRIF_TYPECODE_FLOAT
IEEE 754 single-precision binary floating-point format: binary32.
Definition: xrif.h:229
xrif_undifference
xrif_error_t xrif_undifference(xrif_t handle)
Undifference the image(s)
Definition: xrif.c:1129
xrif_handle::ts_undifference_done
struct timespec ts_undifference_done
Timespec used to mark the end of undifferencing and decoding.
Definition: xrif.h:378
xrif_compress_method_string
const char * xrif_compress_method_string(int compress_method)
Get a string describing the compression method.
Definition: xrif.c:2224
xrif_decompress_none
xrif_error_t xrif_decompress_none(xrif_t handle)
Definition: xrif.c:1962
xrif_reorder
xrif_error_t xrif_reorder(xrif_t handle)
Reorder the data using the method specified by reorder_method
Definition: xrif.c:1227
xrif_handle::encode_rate
double encode_rate
Rate at which the data was encoded in bytes per second.
Definition: xrif.h:362
xrif_reorder_bytepack
xrif_error_t xrif_reorder_bytepack(xrif_t handle)
Dispatch bytepack reodering based on type.
Definition: xrif.c:1305
xrif_reorder_rate
double xrif_reorder_rate(xrif_t handle)
Calculate the reordering rate in bytes/sec.
Definition: xrif.c:2094
xrif_initialize_handle
xrif_error_t xrif_initialize_handle(xrif_t handle)
Initialize an xrif handle object.
Definition: xrif.c:294
XRIF_ERROR_NOTIMPL
#define XRIF_ERROR_NOTIMPL
Return code indicating that the requested feature is not available.
Definition: xrif.h:181
xrif_handle::raw_size
size_t raw_size
Size of the stream before compression. Set dynamically by xrif_set_size or from header.
Definition: xrif.h:317
XRIF_TYPECODE_COMPLEX_FLOAT
#define XRIF_TYPECODE_COMPLEX_FLOAT
complex float
Definition: xrif.h:233
xrif_difference_pixel
xrif_error_t xrif_difference_pixel(xrif_t handle)
Difference the images using the previous pixel as a reference.
Definition: xrif_difference_pixel.c:227
xrif_compression_ratio
double xrif_compression_ratio(xrif_t handle)
Calculate the compression ratio.
Definition: xrif.c:2064
xrif_handle::encode_time
double encode_time
Time in seconds taken to encode the data.
Definition: xrif.h:361
xrif_handle::raw_buffer
char * raw_buffer
The raw buffer pointer, contains the image data, and if compress_on_raw == true the compressed data.
Definition: xrif.h:337
xrif_reset
xrif_error_t xrif_reset(xrif_t handle)
Reset a handle, restoring it to the initialized state. De-allocates owned pointers and re-initializes...
Definition: xrif.c:243
xrif_unreorder_bytepack_sint16
xrif_error_t xrif_unreorder_bytepack_sint16(xrif_t handle)
Perform bytepack unreodering for signed 16 bit ints.
Definition: xrif.c:1682
xrif_handle::reorder_rate
double reorder_rate
Rate at which the data was reordered in bytes per second.
Definition: xrif.h:366
xrif_handle::difference_time
double difference_time
Time in seconds taken to difference the data.
Definition: xrif.h:363
XRIF_ERROR_LIBERR
#define XRIF_ERROR_LIBERR
Return code indicating a library returned an error (e.g. LZ4). The library error code may be added to...
Definition: xrif.h:193
xrif_handle::ts_difference_start
struct timespec ts_difference_start
Timespec used to mark the beginning of differencing, which is also the beginning of encoding.
Definition: xrif.h:370
xrif_min_reordered_size
size_t xrif_min_reordered_size(xrif_t handle)
Calculate the minimum size of the reordered buffer.
Definition: xrif.c:485
XRIF_TYPECODE_HALF
#define XRIF_TYPECODE_HALF
IEEE 754 half-precision 16-bit (uses uint16_t for storage)
Definition: xrif.h:227
xrif_handle::depth
xrif_dimension_t depth
The depth of a single image, in pixels.
Definition: xrif.h:310
xrif_delete
xrif_error_t xrif_delete(xrif_t handle)
Deallocate a handle, including any memory that it owns.
Definition: xrif.c:277
xrif_difference_first
xrif_error_t xrif_difference_first(xrif_t handle)
Difference the images using the first image as a reference.
Definition: xrif_difference_first.c:216
xrif_undifference_previous
xrif_error_t xrif_undifference_previous(xrif_t handle)
Undifference the images using the previous image as a reference.
Definition: xrif_difference_previous.c:384
xrif_decode
xrif_error_t xrif_decode(xrif_t handle)
Decode data from the xrif format.
Definition: xrif.c:1043
xrif_decode_time
double xrif_decode_time(xrif_t handle)
Calculate the time in seconds taken to decode the data.
Definition: xrif.c:2111
xrif_handle::compressed_size
size_t compressed_size
Size of the stream after compression. Set dynamically by compression functions or from header.
Definition: xrif.h:318
XRIF_TYPECODE_INT64
#define XRIF_TYPECODE_INT64
64-bit signed integer
Definition: xrif.h:225
xrif_allocate
xrif_error_t xrif_allocate(xrif_t handle)
Allocate all memory buffers according to the configuration specified in the handle.
Definition: xrif.c:199
xrif_unreorder
xrif_error_t xrif_unreorder(xrif_t handle)
Un-reorder the data using the method specified by reorder_method
Definition: xrif.c:1248
xrif_encode
xrif_error_t xrif_encode(xrif_t handle)
Encode data using the xrif format.
Definition: xrif.c:966
xrif_handle::ts_unreorder_start
struct timespec ts_unreorder_start
Timespec used to mark the beginning of unreordering, which is the end of decompression.
Definition: xrif.h:376
xrif_handle::raw_buffer_size
size_t raw_buffer_size
Definition: xrif.h:338
xrif_typesize
size_t xrif_typesize(xrif_typecode_t type_code)
Return the size of the type specified by the code.
Definition: xrif.c:2150
XRIF_NOERROR
#define XRIF_NOERROR
Return code for success.
Definition: xrif.h:160
xrif_reorder_bitpack
xrif_error_t xrif_reorder_bitpack(xrif_t handle)
Definition: xrif.c:1517
xrif_handle::ts_compress_done
struct timespec ts_compress_done
Timespec used to mark the end of compression and encoding.
Definition: xrif.h:373
XRIF_TYPECODE_UINT16
#define XRIF_TYPECODE_UINT16
16-bit unsigned integer
Definition: xrif.h:215
xrif_set_reorder_method
xrif_error_t xrif_set_reorder_method(xrif_t handle, int reorder_method)
Set the reorder method.
Definition: xrif.c:382
xrif_handle::compressed_buffer_size
size_t compressed_buffer_size
Definition: xrif.h:350
xrif_height
xrif_dimension_t xrif_height(xrif_t handle)
Get the current height of the configured handle.
Definition: xrif.c:812
xrif_handle::own_raw
unsigned char own_raw
Flag (true/false) indicating whether the raw_buffer pointer is managed by this handle.
Definition: xrif.h:336
xrif_handle::data_size
size_t data_size
The size of the pixels, bytes. This corresponds to sizeof(type).
Definition: xrif.h:315
xrif_decompress
xrif_error_t xrif_decompress(xrif_t handle)
Definition: xrif.c:1906
xrif_unreorder_bytepack
xrif_error_t xrif_unreorder_bytepack(xrif_t handle)
Dispatch bytepack unreodering based on type.
Definition: xrif.c:1651
xrif_handle::own_compressed
unsigned char own_compressed
Flag (true/false) indicating whether the compressed_buffer pointer is managed by this handle.
Definition: xrif.h:348
xrif_handle::compress_rate
double compress_rate
Rate at which the data was compressed in bytes per second.
Definition: xrif.h:368
XRIF_ERROR_INSUFFICIENT_SIZE
#define XRIF_ERROR_INSUFFICIENT_SIZE
Return code indicating that an insufficient size was given.
Definition: xrif.h:175
xrif_unreorder_bitpack
xrif_error_t xrif_unreorder_bitpack(xrif_t handle)
Definition: xrif.c:1820
xrif_difference_time
double xrif_difference_time(xrif_t handle)
Calculate the time in seconds taken to difference the data.
Definition: xrif.c:2079
XRIF_ERROR_INVALID_TYPE
#define XRIF_ERROR_INVALID_TYPE
Return code indicating that an invalid type was passed.
Definition: xrif.h:172
xrif_handle::type_code
xrif_typecode_t type_code
The code specifying the data type of the pixels.
Definition: xrif.h:313
xrif_dimension_t
uint32_t xrif_dimension_t
The type used for storing the width and height and depth dimensions of images.
Definition: xrif.h:145
xrif_reorder_none
xrif_error_t xrif_reorder_none(xrif_t handle)
Perform no re-ordering, simply copy raw to reordered.
Definition: xrif.c:1270
xrif_configure
xrif_error_t xrif_configure(xrif_t handle, int difference_method, int reorder_method, int compress_method)
Configure the difference, reorder, and compression methods.
Definition: xrif.c:172
xrif_handle::difference_rate
double difference_rate
Rate at which the data was differenced in bytes per second.
Definition: xrif.h:364
xrif.h
The eXtreme-ao Reordered Image Format: Declarations.
xrif_compress
xrif_error_t xrif_compress(xrif_t handle)
Definition: xrif.c:1888