1 /** @file read_data.c
2 * Matlab MAT version 5 file functions
3 * @ingroup MAT
4 */
5 /*
6 * Copyright (c) 2005-2019, Christopher C. Hulbert
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice, this
13 * list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 /* FIXME: Implement Unicode support */
32 #include <stddef.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <time.h>
38 #include "matio_private.h"
39 #if defined(HAVE_ZLIB)
40 # include <plugin/z/lib/zlib.h>
41 #endif
42
43 #if !defined(READ_BLOCK_SIZE)
44 #define READ_BLOCK_SIZE (256)
45 #endif
46
47 #define READ_DATA_NOSWAP(T) \
48 do { \
49 if ( len <= READ_BLOCK_SIZE ) { \
50 bytesread += fread(v,data_size,len,(FILE*)mat->fp); \
51 for ( j = 0; j < len; j++ ) { \
52 data[j] = (T)v[j]; \
53 } \
54 } else { \
55 for ( i = 0; i < len-READ_BLOCK_SIZE; i+=READ_BLOCK_SIZE ) { \
56 bytesread += fread(v,data_size,READ_BLOCK_SIZE,(FILE*)mat->fp); \
57 for ( j = 0; j < READ_BLOCK_SIZE; j++ ) { \
58 data[i+j] = (T)v[j]; \
59 } \
60 } \
61 if ( len > i ) { \
62 bytesread += fread(v,data_size,len-i,(FILE*)mat->fp); \
63 for ( j = 0; j < len-i; j++ ) { \
64 data[i+j] = (T)v[j]; \
65 } \
66 }\
67 } \
68 } while (0)
69
70 #define READ_DATA(T, SwapFunc) \
71 do { \
72 if ( mat->byteswap ) { \
73 if ( len <= READ_BLOCK_SIZE ) { \
74 bytesread += fread(v,data_size,len,(FILE*)mat->fp); \
75 for ( j = 0; j < len; j++ ) { \
76 data[j] = (T)SwapFunc(&v[j]); \
77 } \
78 } else { \
79 for ( i = 0; i < len-READ_BLOCK_SIZE; i+=READ_BLOCK_SIZE ) { \
80 bytesread += fread(v,data_size,READ_BLOCK_SIZE,(FILE*)mat->fp); \
81 for ( j = 0; j < READ_BLOCK_SIZE; j++ ) { \
82 data[i+j] = (T)SwapFunc(&v[j]); \
83 } \
84 } \
85 if ( len > i ) { \
86 bytesread += fread(v,data_size,len-i,(FILE*)mat->fp); \
87 for ( j = 0; j < len-i; j++ ) { \
88 data[i+j] = (T)SwapFunc(&v[j]); \
89 } \
90 }\
91 } \
92 } else { \
93 READ_DATA_NOSWAP(T); \
94 } \
95 } while (0)
96
97 #ifdef HAVE_MAT_INT64_T
98 #define READ_DATA_INT64(T) \
99 do { \
100 if ( MAT_T_INT64 == data_type ) { \
101 mat_int64_t v[READ_BLOCK_SIZE]; \
102 READ_DATA(T, Mat_int64Swap); \
103 } \
104 } while (0)
105 #else
106 #define READ_DATA_INT64(T)
107 #endif /* HAVE_MAT_INT64_T */
108
109 #ifdef HAVE_MAT_UINT64_T
110 #define READ_DATA_UINT64(T) \
111 do { \
112 if ( MAT_T_UINT64 == data_type ) { \
113 mat_uint64_t v[READ_BLOCK_SIZE]; \
114 READ_DATA(T, Mat_uint64Swap); \
115 } \
116 } while (0)
117 #else
118 #define READ_DATA_UINT64(T)
119 #endif /* HAVE_MAT_UINT64_T */
120
121 #define READ_DATA_TYPE(T) \
122 do { \
123 switch ( data_type ) { \
124 case MAT_T_DOUBLE: \
125 { \
126 double v[READ_BLOCK_SIZE]; \
127 READ_DATA(T, Mat_doubleSwap); \
128 break; \
129 } \
130 case MAT_T_SINGLE: \
131 { \
132 float v[READ_BLOCK_SIZE]; \
133 READ_DATA(T, Mat_floatSwap); \
134 break; \
135 } \
136 case MAT_T_INT32: \
137 { \
138 mat_int32_t v[READ_BLOCK_SIZE]; \
139 READ_DATA(T, Mat_int32Swap); \
140 break; \
141 } \
142 case MAT_T_UINT32: \
143 { \
144 mat_uint32_t v[READ_BLOCK_SIZE]; \
145 READ_DATA(T, Mat_uint32Swap); \
146 break; \
147 } \
148 case MAT_T_INT16: \
149 { \
150 mat_int16_t v[READ_BLOCK_SIZE]; \
151 READ_DATA(T, Mat_int16Swap); \
152 break; \
153 } \
154 case MAT_T_UINT16: \
155 { \
156 mat_uint16_t v[READ_BLOCK_SIZE]; \
157 READ_DATA(T, Mat_uint16Swap); \
158 break; \
159 } \
160 case MAT_T_INT8: \
161 { \
162 mat_int8_t v[READ_BLOCK_SIZE]; \
163 READ_DATA_NOSWAP(T); \
164 break; \
165 } \
166 case MAT_T_UINT8: \
167 { \
168 mat_uint8_t v[READ_BLOCK_SIZE]; \
169 READ_DATA_NOSWAP(T); \
170 break; \
171 } \
172 default: \
173 READ_DATA_INT64(T); \
174 READ_DATA_UINT64(T); \
175 break; \
176 } \
177 } while (0)
178
179 #if defined(HAVE_ZLIB)
180 #define READ_COMPRESSED_DATA(T, SwapFunc) \
181 do { \
182 if ( mat->byteswap ) { \
183 for ( i = 0; i < len; i++ ) { \
184 InflateData(mat,z,&v,data_size); \
185 data[i] = (T)SwapFunc(&v); \
186 } \
187 } else { \
188 for ( i = 0; i < len; i++ ) { \
189 InflateData(mat,z,&v,data_size); \
190 data[i] = (T)v; \
191 } \
192 } \
193 } while (0)
194
195 #ifdef HAVE_MAT_INT64_T
196 #define READ_COMPRESSED_DATA_INT64(T) \
197 do { \
198 if ( MAT_T_INT64 == data_type ) { \
199 mat_int64_t v; \
200 READ_COMPRESSED_DATA(T, Mat_int64Swap); \
201 } \
202 } while (0)
203 #else
204 #define READ_COMPRESSED_DATA_INT64(T)
205 #endif /* HAVE_MAT_INT64_T */
206
207 #ifdef HAVE_MAT_UINT64_T
208 #define READ_COMPRESSED_DATA_UINT64(T) \
209 do { \
210 if ( MAT_T_UINT64 == data_type ) { \
211 mat_uint64_t v; \
212 READ_COMPRESSED_DATA(T, Mat_uint64Swap); \
213 } \
214 } while (0)
215 #else
216 #define READ_COMPRESSED_DATA_UINT64(T)
217 #endif /* HAVE_MAT_UINT64_T */
218
219 #define READ_COMPRESSED_DATA_TYPE(T) \
220 do { \
221 switch ( data_type ) { \
222 case MAT_T_DOUBLE: \
223 { \
224 double v; \
225 READ_COMPRESSED_DATA(T, Mat_doubleSwap); \
226 break; \
227 } \
228 case MAT_T_SINGLE: \
229 { \
230 float v; \
231 READ_COMPRESSED_DATA(T, Mat_floatSwap); \
232 break; \
233 } \
234 case MAT_T_INT32: \
235 { \
236 mat_int32_t v; \
237 READ_COMPRESSED_DATA(T, Mat_int32Swap); \
238 break; \
239 } \
240 case MAT_T_UINT32: \
241 { \
242 mat_uint32_t v; \
243 READ_COMPRESSED_DATA(T, Mat_uint32Swap); \
244 break; \
245 } \
246 case MAT_T_INT16: \
247 { \
248 mat_int16_t v; \
249 READ_COMPRESSED_DATA(T, Mat_int16Swap); \
250 break; \
251 } \
252 case MAT_T_UINT16: \
253 { \
254 mat_uint16_t v; \
255 READ_COMPRESSED_DATA(T, Mat_uint16Swap); \
256 break; \
257 } \
258 case MAT_T_UINT8: \
259 { \
260 mat_uint8_t v; \
261 for ( i = 0; i < len; i++ ) { \
262 InflateData(mat,z,&v,data_size); \
263 data[i] = (T)v; \
264 } \
265 break; \
266 } \
267 case MAT_T_INT8: \
268 { \
269 mat_int8_t v; \
270 for ( i = 0; i < len; i++ ) { \
271 InflateData(mat,z,&v,data_size); \
272 data[i] = (T)v; \
273 } \
274 break; \
275 } \
276 default: \
277 READ_COMPRESSED_DATA_INT64(T); \
278 READ_COMPRESSED_DATA_UINT64(T); \
279 break; \
280 } \
281 } while (0)
282 #endif
283
284 /*
285 * --------------------------------------------------------------------------
286 * Routines to read data of any type into arrays of a specific type
287 * --------------------------------------------------------------------------
288 */
289
290 /** @cond mat_devman */
291
292 /** @brief Reads data of type @c data_type into a double type
293 *
294 * Reads from the MAT file @c len elements of data type @c data_type storing
295 * them as double's in @c data.
296 * @ingroup mat_internal
297 * @param mat MAT file pointer
298 * @param data Pointer to store the output double values (len*sizeof(double))
299 * @param data_type one of the @c matio_types enumerations which is the source
300 * data type in the file
301 * @param len Number of elements of type @c data_type to read from the file
302 * @retval Number of bytes read from the file
303 */
304 int
ReadDoubleData(mat_t * mat,double * data,enum matio_types data_type,int len)305 ReadDoubleData(mat_t *mat,double *data,enum matio_types data_type,int len)
306 {
307 int bytesread = 0, i, j;
308 size_t data_size;
309
310 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
311 return 0;
312
313 data_size = Mat_SizeOf(data_type);
314
315 switch ( data_type ) {
316 case MAT_T_DOUBLE:
317 {
318 bytesread += fread(data,data_size,len,(FILE*)mat->fp);
319 if ( mat->byteswap ) {
320 for ( i = 0; i < len; i++ ) {
321 (void)Mat_doubleSwap(data+i);
322 }
323 }
324 break;
325 }
326 case MAT_T_SINGLE:
327 {
328 float v[READ_BLOCK_SIZE];
329 READ_DATA(double, Mat_floatSwap);
330 break;
331 }
332 #ifdef HAVE_MAT_INT64_T
333 case MAT_T_INT64:
334 {
335 mat_int64_t v[READ_BLOCK_SIZE];
336 READ_DATA(double, Mat_int64Swap);
337 break;
338 }
339 #endif
340 #ifdef HAVE_MAT_UINT64_T
341 case MAT_T_UINT64:
342 {
343 mat_uint64_t v[READ_BLOCK_SIZE];
344 READ_DATA(double, Mat_uint64Swap);
345 break;
346 }
347 #endif
348 case MAT_T_INT32:
349 {
350 mat_int32_t v[READ_BLOCK_SIZE];
351 READ_DATA(double, Mat_int32Swap);
352 break;
353 }
354 case MAT_T_UINT32:
355 {
356 mat_uint32_t v[READ_BLOCK_SIZE];
357 READ_DATA(double, Mat_uint32Swap);
358 break;
359 }
360 case MAT_T_INT16:
361 {
362 mat_int16_t v[READ_BLOCK_SIZE];
363 READ_DATA(double, Mat_int16Swap);
364 break;
365 }
366 case MAT_T_UINT16:
367 {
368 mat_uint16_t v[READ_BLOCK_SIZE];
369 READ_DATA(double, Mat_uint16Swap);
370 break;
371 }
372 case MAT_T_INT8:
373 {
374 mat_int8_t v[READ_BLOCK_SIZE];
375 READ_DATA_NOSWAP(double);
376 break;
377 }
378 case MAT_T_UINT8:
379 {
380 mat_uint8_t v[READ_BLOCK_SIZE];
381 READ_DATA_NOSWAP(double);
382 break;
383 }
384 default:
385 return 0;
386 }
387 bytesread *= data_size;
388 return bytesread;
389 }
390
391 #if defined(HAVE_ZLIB)
392 /** @brief Reads data of type @c data_type into a double type
393 *
394 * Reads from the MAT file @c len compressed elements of data type @c data_type
395 * storing them as double's in @c data.
396 * @ingroup mat_internal
397 * @param mat MAT file pointer
398 * @param z Pointer to the zlib stream for inflation
399 * @param data Pointer to store the output double values (len*sizeof(double))
400 * @param data_type one of the @c matio_types enumerations which is the source
401 * data type in the file
402 * @param len Number of elements of type @c data_type to read from the file
403 * @retval Number of bytes read from the file
404 */
405 int
ReadCompressedDoubleData(mat_t * mat,z_streamp z,double * data,enum matio_types data_type,int len)406 ReadCompressedDoubleData(mat_t *mat,z_streamp z,double *data,
407 enum matio_types data_type,int len)
408 {
409 int nBytes = 0, i;
410 unsigned int data_size;
411 union _buf {
412 float f[256];
413 #ifdef HAVE_MAT_INT64_T
414 mat_int64_t i64[128];
415 #endif
416 #ifdef HAVE_MAT_UINT64_T
417 mat_uint64_t ui64[128];
418 #endif
419 mat_int32_t i32[256];
420 mat_uint32_t ui32[256];
421 mat_int16_t i16[512];
422 mat_uint16_t ui16[512];
423 mat_int8_t i8[1024];
424 mat_uint8_t ui8[1024];
425 } buf;
426
427 data_size = (unsigned int)Mat_SizeOf(data_type);
428
429 switch ( data_type ) {
430 case MAT_T_DOUBLE:
431 {
432 if ( mat->byteswap ) {
433 InflateData(mat,z,data,len*data_size);
434 for ( i = 0; i < len; i++ )
435 (void)Mat_doubleSwap(data+i);
436 } else {
437 InflateData(mat,z,data,len*data_size);
438 }
439 break;
440 }
441 case MAT_T_SINGLE:
442 {
443 if ( mat->byteswap ) {
444 if ( len <= 256 ){
445 InflateData(mat,z,buf.f,len*data_size);
446 for ( i = 0; i < len; i++ )
447 data[i] = Mat_floatSwap(buf.f+i);
448 } else {
449 int j;
450 len -= 256;
451 for ( i = 0; i < len; i+=256 ) {
452 InflateData(mat,z,buf.f,256*data_size);
453 for ( j = 0; j < 256; j++ )
454 data[i+j] = Mat_floatSwap(buf.f+j);
455 }
456 len = len-(i-256);
457 InflateData(mat,z,buf.f,len*data_size);
458 for ( j = 0; j < len; j++ )
459 data[i+j] = Mat_floatSwap(buf.f+j);
460 }
461 } else {
462 if ( len <= 256 ){
463 InflateData(mat,z,buf.f,len*data_size);
464 for ( i = 0; i < len; i++ )
465 data[i] = buf.f[i];
466 } else {
467 int j;
468 len -= 256;
469 for ( i = 0; i < len; i+=256 ) {
470 InflateData(mat,z,buf.f,256*data_size);
471 for ( j = 0; j < 256; j++ )
472 data[i+j] = buf.f[j];
473 }
474 len = len-(i-256);
475 InflateData(mat,z,buf.f,len*data_size);
476 for ( j = 0; j < len; j++ )
477 data[i+j] = buf.f[j];
478 }
479 }
480 break;
481 }
482 #ifdef HAVE_MAT_INT64_T
483 case MAT_T_INT64:
484 {
485 if ( mat->byteswap ) {
486 if ( len <= 128 ){
487 InflateData(mat,z,buf.i64,len*data_size);
488 for ( i = 0; i < len; i++ )
489 data[i] = (double)Mat_int64Swap(buf.i64+i);
490 } else {
491 int j;
492 len -= 128;
493 for ( i = 0; i < len; i+=128 ) {
494 InflateData(mat,z,buf.i64,128*data_size);
495 for ( j = 0; j < 128; j++ )
496 data[i+j] = (double)Mat_int64Swap(buf.i64+j);
497 }
498 len = len-(i-128);
499 InflateData(mat,z,buf.i64,len*data_size);
500 for ( j = 0; j < len; j++ )
501 data[i+j] = (double)Mat_int64Swap(buf.i64+j);
502 }
503 } else {
504 if ( len <= 128 ){
505 InflateData(mat,z,buf.i64,len*data_size);
506 for ( i = 0; i < len; i++ )
507 data[i] = (double)buf.i64[i];
508 } else {
509 int j;
510 len -= 128;
511 for ( i = 0; i < len; i+=128 ) {
512 InflateData(mat,z,buf.i64,128*data_size);
513 for ( j = 0; j < 128; j++ )
514 data[i+j] = (double)buf.i64[j];
515 }
516 len = len-(i-128);
517 InflateData(mat,z,buf.i64,len*data_size);
518 for ( j = 0; j < len; j++ )
519 data[i+j] = (double)buf.i64[j];
520 }
521 }
522 break;
523 }
524 #endif
525 #ifdef HAVE_MAT_UINT64_T
526 case MAT_T_UINT64:
527 {
528 if ( mat->byteswap ) {
529 if ( len <= 128 ){
530 InflateData(mat,z,buf.ui64,len*data_size);
531 for ( i = 0; i < len; i++ )
532 data[i] = (double)Mat_uint64Swap(buf.ui64+i);
533 } else {
534 int j;
535 len -= 128;
536 for ( i = 0; i < len; i+=128 ) {
537 InflateData(mat,z,buf.ui64,128*data_size);
538 for ( j = 0; j < 128; j++ )
539 data[i+j] = (double)Mat_uint64Swap(buf.ui64+j);
540 }
541 len = len-(i-128);
542 InflateData(mat,z,buf.ui64,len*data_size);
543 for ( j = 0; j < len; j++ )
544 data[i+j] = (double)Mat_uint64Swap(buf.ui64+j);
545 }
546 } else {
547 if ( len <= 128 ){
548 InflateData(mat,z,buf.ui64,len*data_size);
549 for ( i = 0; i < len; i++ )
550 data[i] = (double)buf.ui64[i];
551 } else {
552 int j;
553 len -= 128;
554 for ( i = 0; i < len; i+=128 ) {
555 InflateData(mat,z,buf.ui64,128*data_size);
556 for ( j = 0; j < 128; j++ )
557 data[i+j] = (double)buf.ui64[j];
558 }
559 len = len-(i-128);
560 InflateData(mat,z,buf.ui64,len*data_size);
561 for ( j = 0; j < len; j++ )
562 data[i+j] = (double)buf.ui64[j];
563 }
564 }
565 break;
566 }
567 #endif
568 case MAT_T_INT32:
569 {
570 if ( mat->byteswap ) {
571 if ( len <= 256 ){
572 InflateData(mat,z,buf.i32,len*data_size);
573 for ( i = 0; i < len; i++ )
574 data[i] = Mat_int32Swap(buf.i32+i);
575 } else {
576 int j;
577 len -= 256;
578 for ( i = 0; i < len; i+=256 ) {
579 InflateData(mat,z,buf.i32,256*data_size);
580 for ( j = 0; j < 256; j++ )
581 data[i+j] = Mat_int32Swap(buf.i32+j);
582 }
583 len = len-(i-256);
584 InflateData(mat,z,buf.i32,len*data_size);
585 for ( j = 0; j < len; j++ )
586 data[i+j] = Mat_int32Swap(buf.i32+j);
587 }
588 } else {
589 if ( len <= 256 ){
590 InflateData(mat,z,buf.i32,len*data_size);
591 for ( i = 0; i < len; i++ )
592 data[i] = buf.i32[i];
593 } else {
594 int j;
595 len -= 256;
596 for ( i = 0; i < len; i+=256 ) {
597 InflateData(mat,z,buf.i32,256*data_size);
598 for ( j = 0; j < 256; j++ )
599 data[i+j] = buf.i32[j];
600 }
601 len = len-(i-256);
602 InflateData(mat,z,buf.i32,len*data_size);
603 for ( j = 0; j < len; j++ )
604 data[i+j] = buf.i32[j];
605 }
606 }
607 break;
608 }
609 case MAT_T_UINT32:
610 {
611 if ( mat->byteswap ) {
612 if ( len <= 256 ){
613 InflateData(mat,z,buf.ui32,len*data_size);
614 for ( i = 0; i < len; i++ )
615 data[i] = Mat_uint32Swap(buf.ui32+i);
616 } else {
617 int j;
618 len -= 256;
619 for ( i = 0; i < len; i+=256 ) {
620 InflateData(mat,z,buf.ui32,256*data_size);
621 for ( j = 0; j < 256; j++ )
622 data[i+j] = Mat_uint32Swap(buf.ui32+j);
623 }
624 len = len-(i-256);
625 InflateData(mat,z,buf.ui32,len*data_size);
626 for ( j = 0; j < len; j++ )
627 data[i+j] = Mat_uint32Swap(buf.ui32+j);
628 }
629 } else {
630 if ( len <= 256 ) {
631 InflateData(mat,z,buf.ui32,len*data_size);
632 for ( i = 0; i < len; i++ )
633 data[i] = buf.ui32[i];
634 } else {
635 int j;
636 len -= 256;
637 for ( i = 0; i < len; i+=256 ) {
638 InflateData(mat,z,buf.ui32,256*data_size);
639 for ( j = 0; j < 256; j++ )
640 data[i+j] = buf.ui32[j];
641 }
642 len = len-(i-256);
643 InflateData(mat,z,buf.ui32,len*data_size);
644 for ( j = 0; j < len; j++ )
645 data[i+j] = buf.ui32[j];
646 }
647 }
648 break;
649 }
650 case MAT_T_INT16:
651 {
652 if ( mat->byteswap ) {
653 if ( len <= 512 ){
654 InflateData(mat,z,buf.i16,len*data_size);
655 for ( i = 0; i < len; i++ )
656 data[i] = Mat_int16Swap(buf.i16+i);
657 } else {
658 int j;
659 len -= 512;
660 for ( i = 0; i < len; i+=512 ) {
661 InflateData(mat,z,buf.i16,512*data_size);
662 for ( j = 0; j < 512; j++ )
663 data[i+j] = Mat_int16Swap(buf.i16+j);
664 }
665 len = len-(i-512);
666 InflateData(mat,z,buf.i16,len*data_size);
667 for ( j = 0; j < len; j++ )
668 data[i+j] = Mat_int16Swap(buf.i16+j);
669 }
670 } else {
671 if ( len <= 512 ) {
672 InflateData(mat,z,buf.i16,len*data_size);
673 for ( i = 0; i < len; i++ )
674 data[i] = buf.i16[i];
675 } else {
676 int j;
677 len -= 512;
678 for ( i = 0; i < len; i+=512 ) {
679 InflateData(mat,z,buf.i16,512*data_size);
680 for ( j = 0; j < 512; j++ )
681 data[i+j] = buf.i16[j];
682 }
683 len = len-(i-512);
684 InflateData(mat,z,buf.i16,len*data_size);
685 for ( j = 0; j < len; j++ )
686 data[i+j] = buf.i16[j];
687 }
688 }
689 break;
690 }
691 case MAT_T_UINT16:
692 {
693 if ( mat->byteswap ) {
694 if ( len <= 512 ){
695 InflateData(mat,z,buf.ui16,len*data_size);
696 for ( i = 0; i < len; i++ )
697 data[i] = Mat_uint16Swap(buf.ui16+i);
698 } else {
699 int j;
700 len -= 512;
701 for ( i = 0; i < len; i+=512 ) {
702 InflateData(mat,z,buf.ui16,512*data_size);
703 for ( j = 0; j < 512; j++ )
704 data[i+j] = Mat_uint16Swap(buf.ui16+j);
705 }
706 len = len-(i-512);
707 InflateData(mat,z,buf.ui16,len*data_size);
708 for ( j = 0; j < len; j++ )
709 data[i+j] = Mat_uint16Swap(buf.ui16+j);
710 }
711 } else {
712 if ( len <= 512 ) {
713 InflateData(mat,z,buf.ui16,len*data_size);
714 for ( i = 0; i < len; i++ )
715 data[i] = buf.ui16[i];
716 } else {
717 int j;
718 len -= 512;
719 for ( i = 0; i < len; i+=512 ) {
720 InflateData(mat,z,buf.ui16,512*data_size);
721 for ( j = 0; j < 512; j++ )
722 data[i+j] = buf.ui16[j];
723 }
724 len = len-(i-512);
725 InflateData(mat,z,buf.ui16,len*data_size);
726 for ( j = 0; j < len; j++ )
727 data[i+j] = buf.ui16[j];
728 }
729 }
730 break;
731 }
732 case MAT_T_UINT8:
733 {
734 if ( len <= 1024 ) {
735 InflateData(mat,z,buf.ui8,len*data_size);
736 for ( i = 0; i < len; i++ )
737 data[i] = buf.ui8[i];
738 } else {
739 int j;
740 len -= 1024;
741 for ( i = 0; i < len; i+=1024 ) {
742 InflateData(mat,z,buf.ui8,1024*data_size);
743 for ( j = 0; j < 1024; j++ )
744 data[i+j] = buf.ui8[j];
745 }
746 len = len-(i-1024);
747 InflateData(mat,z,buf.ui8,len*data_size);
748 for ( j = 0; j < len; j++ )
749 data[i+j] = buf.ui8[j];
750 }
751 break;
752 }
753 case MAT_T_INT8:
754 {
755 if ( len <= 1024 ) {
756 InflateData(mat,z,buf.i8,len*data_size);
757 for ( i = 0; i < len; i++ )
758 data[i] = buf.i8[i];
759 } else {
760 int j;
761 len -= 1024;
762 for ( i = 0; i < len; i+=1024 ) {
763 InflateData(mat,z,buf.i8,1024*data_size);
764 for ( j = 0; j < 1024; j++ )
765 data[i+j] = buf.i8[j];
766 }
767 len = len-(i-1024);
768 InflateData(mat,z,buf.i8,len*data_size);
769 for ( j = 0; j < len; j++ )
770 data[i+j] = buf.i8[j];
771 }
772 break;
773 }
774 default:
775 return 0;
776 }
777 nBytes = len*data_size;
778 return nBytes;
779 }
780 #endif
781
782 /** @brief Reads data of type @c data_type into a float type
783 *
784 * Reads from the MAT file @c len elements of data type @c data_type storing
785 * them as float's in @c data.
786 * @ingroup mat_internal
787 * @param mat MAT file pointer
788 * @param data Pointer to store the output float values (len*sizeof(float))
789 * @param data_type one of the @c matio_types enumerations which is the source
790 * data type in the file
791 * @param len Number of elements of type @c data_type to read from the file
792 * @retval Number of bytes read from the file
793 */
794 int
ReadSingleData(mat_t * mat,float * data,enum matio_types data_type,int len)795 ReadSingleData(mat_t *mat,float *data,enum matio_types data_type,int len)
796 {
797 int bytesread = 0, i, j;
798 size_t data_size;
799
800 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
801 return 0;
802
803 data_size = Mat_SizeOf(data_type);
804 READ_DATA_TYPE(float);
805 bytesread *= data_size;
806 return bytesread;
807 }
808
809 #if defined(HAVE_ZLIB)
810 /** @brief Reads data of type @c data_type into a float type
811 *
812 * Reads from the MAT file @c len compressed elements of data type @c data_type
813 * storing them as float's in @c data.
814 * @ingroup mat_internal
815 * @param mat MAT file pointer
816 * @param z Pointer to the zlib stream for inflation
817 * @param data Pointer to store the output float values (len*sizeof(float))
818 * @param data_type one of the @c matio_types enumerations which is the source
819 * data type in the file
820 * @param len Number of elements of type @c data_type to read from the file
821 * @retval Number of bytes read from the file
822 */
823 int
ReadCompressedSingleData(mat_t * mat,z_streamp z,float * data,enum matio_types data_type,int len)824 ReadCompressedSingleData(mat_t *mat,z_streamp z,float *data,
825 enum matio_types data_type,int len)
826 {
827 int nBytes = 0, i;
828 unsigned int data_size;
829
830 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
831 return 0;
832
833 data_size = (unsigned int)Mat_SizeOf(data_type);
834 READ_COMPRESSED_DATA_TYPE(float);
835 nBytes = len*data_size;
836 return nBytes;
837 }
838 #endif
839
840 #ifdef HAVE_MAT_INT64_T
841 /** @brief Reads data of type @c data_type into a signed 64-bit integer type
842 *
843 * Reads from the MAT file @c len elements of data type @c data_type storing
844 * them as signed 64-bit integers in @c data.
845 * @ingroup mat_internal
846 * @param mat MAT file pointer
847 * @param data Pointer to store the output signed 64-bit integer values
848 * (len*sizeof(mat_int64_t))
849 * @param data_type one of the @c matio_types enumerations which is the source
850 * data type in the file
851 * @param len Number of elements of type @c data_type to read from the file
852 * @retval Number of bytes read from the file
853 */
854 int
ReadInt64Data(mat_t * mat,mat_int64_t * data,enum matio_types data_type,int len)855 ReadInt64Data(mat_t *mat,mat_int64_t *data,enum matio_types data_type,int len)
856 {
857 int bytesread = 0, i, j;
858 size_t data_size;
859
860 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
861 return 0;
862
863 data_size = Mat_SizeOf(data_type);
864 READ_DATA_TYPE(mat_int64_t);
865 bytesread *= data_size;
866 return bytesread;
867 }
868
869 #if defined(HAVE_ZLIB)
870 /** @brief Reads data of type @c data_type into a signed 64-bit integer type
871 *
872 * Reads from the MAT file @c len compressed elements of data type @c data_type
873 * storing them as signed 64-bit integers in @c data.
874 * @ingroup mat_internal
875 * @param mat MAT file pointer
876 * @param z Pointer to the zlib stream for inflation
877 * @param data Pointer to store the output signed 64-bit integer values
878 * (len*sizeof(mat_int64_t))
879 * @param data_type one of the @c matio_types enumerations which is the source
880 * data type in the file
881 * @param len Number of elements of type @c data_type to read from the file
882 * @retval Number of bytes read from the file
883 */
884 int
ReadCompressedInt64Data(mat_t * mat,z_streamp z,mat_int64_t * data,enum matio_types data_type,int len)885 ReadCompressedInt64Data(mat_t *mat,z_streamp z,mat_int64_t *data,
886 enum matio_types data_type,int len)
887 {
888 int nBytes = 0, i;
889 unsigned int data_size;
890
891 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
892 return 0;
893
894 data_size = (unsigned int)Mat_SizeOf(data_type);
895 READ_COMPRESSED_DATA_TYPE(mat_int64_t);
896 nBytes = len*data_size;
897 return nBytes;
898 }
899 #endif
900 #endif /* HAVE_MAT_INT64_T */
901
902 #ifdef HAVE_MAT_UINT64_T
903 /** @brief Reads data of type @c data_type into an unsigned 64-bit integer type
904 *
905 * Reads from the MAT file @c len elements of data type @c data_type storing
906 * them as unsigned 64-bit integers in @c data.
907 * @ingroup mat_internal
908 * @param mat MAT file pointer
909 * @param data Pointer to store the output unsigned 64-bit integer values
910 * (len*sizeof(mat_uint64_t))
911 * @param data_type one of the @c matio_types enumerations which is the source
912 * data type in the file
913 * @param len Number of elements of type @c data_type to read from the file
914 * @retval Number of bytes read from the file
915 */
916 int
ReadUInt64Data(mat_t * mat,mat_uint64_t * data,enum matio_types data_type,int len)917 ReadUInt64Data(mat_t *mat,mat_uint64_t *data,enum matio_types data_type,int len)
918 {
919 int bytesread = 0, i, j;
920 size_t data_size;
921
922 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
923 return 0;
924
925 data_size = Mat_SizeOf(data_type);
926 READ_DATA_TYPE(mat_uint64_t);
927 bytesread *= data_size;
928 return bytesread;
929 }
930
931 #if defined(HAVE_ZLIB)
932 /** @brief Reads data of type @c data_type into an unsigned 64-bit integer type
933 *
934 * Reads from the MAT file @c len compressed elements of data type @c data_type
935 * storing them as unsigned 64-bit integers in @c data.
936 * @ingroup mat_internal
937 * @param mat MAT file pointer
938 * @param z Pointer to the zlib stream for inflation
939 * @param data Pointer to store the output unsigned 64-bit integer values
940 * (len*sizeof(mat_uint64_t))
941 * @param data_type one of the @c matio_types enumerations which is the source
942 * data type in the file
943 * @param len Number of elements of type @c data_type to read from the file
944 * @retval Number of bytes read from the file
945 */
946 int
ReadCompressedUInt64Data(mat_t * mat,z_streamp z,mat_uint64_t * data,enum matio_types data_type,int len)947 ReadCompressedUInt64Data(mat_t *mat,z_streamp z,mat_uint64_t *data,
948 enum matio_types data_type,int len)
949 {
950 int nBytes = 0, i;
951 unsigned int data_size;
952
953 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
954 return 0;
955
956 data_size = (unsigned int)Mat_SizeOf(data_type);
957 READ_COMPRESSED_DATA_TYPE(mat_uint64_t);
958 nBytes = len*data_size;
959 return nBytes;
960 }
961 #endif /* HAVE_ZLIB */
962 #endif /* HAVE_MAT_UINT64_T */
963
964 /** @brief Reads data of type @c data_type into a signed 32-bit integer type
965 *
966 * Reads from the MAT file @c len elements of data type @c data_type storing
967 * them as signed 32-bit integers in @c data.
968 * @ingroup mat_internal
969 * @param mat MAT file pointer
970 * @param data Pointer to store the output signed 32-bit integer values
971 * (len*sizeof(mat_int32_t))
972 * @param data_type one of the @c matio_types enumerations which is the source
973 * data type in the file
974 * @param len Number of elements of type @c data_type to read from the file
975 * @retval Number of bytes read from the file
976 */
977 int
ReadInt32Data(mat_t * mat,mat_int32_t * data,enum matio_types data_type,int len)978 ReadInt32Data(mat_t *mat,mat_int32_t *data,enum matio_types data_type,int len)
979 {
980 int bytesread = 0, i, j;
981 size_t data_size;
982
983 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
984 return 0;
985
986 data_size = Mat_SizeOf(data_type);
987 READ_DATA_TYPE(mat_int32_t);
988 bytesread *= data_size;
989 return bytesread;
990 }
991
992 #if defined(HAVE_ZLIB)
993 /** @brief Reads data of type @c data_type into a signed 32-bit integer type
994 *
995 * Reads from the MAT file @c len compressed elements of data type @c data_type
996 * storing them as signed 32-bit integers in @c data.
997 * @ingroup mat_internal
998 * @param mat MAT file pointer
999 * @param z Pointer to the zlib stream for inflation
1000 * @param data Pointer to store the output signed 32-bit integer values
1001 * (len*sizeof(mat_int32_t))
1002 * @param data_type one of the @c matio_types enumerations which is the source
1003 * data type in the file
1004 * @param len Number of elements of type @c data_type to read from the file
1005 * @retval Number of bytes read from the file
1006 */
1007 int
ReadCompressedInt32Data(mat_t * mat,z_streamp z,mat_int32_t * data,enum matio_types data_type,int len)1008 ReadCompressedInt32Data(mat_t *mat,z_streamp z,mat_int32_t *data,
1009 enum matio_types data_type,int len)
1010 {
1011 int nBytes = 0, i;
1012 unsigned int data_size;
1013
1014 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1015 return 0;
1016
1017 data_size = (unsigned int)Mat_SizeOf(data_type);
1018 READ_COMPRESSED_DATA_TYPE(mat_int32_t);
1019 nBytes = len*data_size;
1020 return nBytes;
1021 }
1022 #endif
1023
1024 /** @brief Reads data of type @c data_type into an unsigned 32-bit integer type
1025 *
1026 * Reads from the MAT file @c len elements of data type @c data_type storing
1027 * them as unsigned 32-bit integers in @c data.
1028 * @ingroup mat_internal
1029 * @param mat MAT file pointer
1030 * @param data Pointer to store the output unsigned 32-bit integer values
1031 * (len*sizeof(mat_uint32_t))
1032 * @param data_type one of the @c matio_types enumerations which is the source
1033 * data type in the file
1034 * @param len Number of elements of type @c data_type to read from the file
1035 * @retval Number of bytes read from the file
1036 */
1037 int
ReadUInt32Data(mat_t * mat,mat_uint32_t * data,enum matio_types data_type,int len)1038 ReadUInt32Data(mat_t *mat,mat_uint32_t *data,enum matio_types data_type,int len)
1039 {
1040 int bytesread = 0, i, j;
1041 size_t data_size;
1042
1043 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
1044 return 0;
1045
1046 data_size = Mat_SizeOf(data_type);
1047 READ_DATA_TYPE(mat_uint32_t);
1048 bytesread *= data_size;
1049 return bytesread;
1050 }
1051
1052 #if defined(HAVE_ZLIB)
1053 /** @brief Reads data of type @c data_type into an unsigned 32-bit integer type
1054 *
1055 * Reads from the MAT file @c len compressed elements of data type @c data_type
1056 * storing them as unsigned 32-bit integers in @c data.
1057 * @ingroup mat_internal
1058 * @param mat MAT file pointer
1059 * @param z Pointer to the zlib stream for inflation
1060 * @param data Pointer to store the output unsigned 32-bit integer values
1061 * (len*sizeof(mat_uint32_t))
1062 * @param data_type one of the @c matio_types enumerations which is the source
1063 * data type in the file
1064 * @param len Number of elements of type @c data_type to read from the file
1065 * @retval Number of bytes read from the file
1066 */
1067 int
ReadCompressedUInt32Data(mat_t * mat,z_streamp z,mat_uint32_t * data,enum matio_types data_type,int len)1068 ReadCompressedUInt32Data(mat_t *mat,z_streamp z,mat_uint32_t *data,
1069 enum matio_types data_type,int len)
1070 {
1071 int nBytes = 0, i;
1072 unsigned int data_size;
1073
1074 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1075 return 0;
1076
1077 data_size = (unsigned int)Mat_SizeOf(data_type);
1078 READ_COMPRESSED_DATA_TYPE(mat_uint32_t);
1079 nBytes = len*data_size;
1080 return nBytes;
1081 }
1082 #endif
1083
1084 /** @brief Reads data of type @c data_type into a signed 16-bit integer type
1085 *
1086 * Reads from the MAT file @c len elements of data type @c data_type storing
1087 * them as signed 16-bit integers in @c data.
1088 * @ingroup mat_internal
1089 * @param mat MAT file pointer
1090 * @param data Pointer to store the output signed 16-bit integer values
1091 * (len*sizeof(mat_int16_t))
1092 * @param data_type one of the @c matio_types enumerations which is the source
1093 * data type in the file
1094 * @param len Number of elements of type @c data_type to read from the file
1095 * @retval Number of bytes read from the file
1096 */
1097 int
ReadInt16Data(mat_t * mat,mat_int16_t * data,enum matio_types data_type,int len)1098 ReadInt16Data(mat_t *mat,mat_int16_t *data,enum matio_types data_type,int len)
1099 {
1100 int bytesread = 0, i, j;
1101 size_t data_size;
1102
1103 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
1104 return 0;
1105
1106 data_size = Mat_SizeOf(data_type);
1107 READ_DATA_TYPE(mat_int16_t);
1108 bytesread *= data_size;
1109 return bytesread;
1110 }
1111
1112 #if defined(HAVE_ZLIB)
1113 /** @brief Reads data of type @c data_type into a signed 16-bit integer type
1114 *
1115 * Reads from the MAT file @c len compressed elements of data type @c data_type
1116 * storing them as signed 16-bit integers in @c data.
1117 * @ingroup mat_internal
1118 * @param mat MAT file pointer
1119 * @param z Pointer to the zlib stream for inflation
1120 * @param data Pointer to store the output signed 16-bit integer values
1121 * (len*sizeof(mat_int16_t))
1122 * @param data_type one of the @c matio_types enumerations which is the source
1123 * data type in the file
1124 * @param len Number of elements of type @c data_type to read from the file
1125 * @retval Number of bytes read from the file
1126 */
1127 int
ReadCompressedInt16Data(mat_t * mat,z_streamp z,mat_int16_t * data,enum matio_types data_type,int len)1128 ReadCompressedInt16Data(mat_t *mat,z_streamp z,mat_int16_t *data,
1129 enum matio_types data_type,int len)
1130 {
1131 int nBytes = 0, i;
1132 unsigned int data_size;
1133
1134 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1135 return 0;
1136
1137 data_size = (unsigned int)Mat_SizeOf(data_type);
1138 READ_COMPRESSED_DATA_TYPE(mat_int16_t);
1139 nBytes = len*data_size;
1140 return nBytes;
1141 }
1142 #endif
1143
1144 /** @brief Reads data of type @c data_type into an unsigned 16-bit integer type
1145 *
1146 * Reads from the MAT file @c len elements of data type @c data_type storing
1147 * them as unsigned 16-bit integers in @c data.
1148 * @ingroup mat_internal
1149 * @param mat MAT file pointer
1150 * @param data Pointer to store the output unsigned 16-bit integer values
1151 * (len*sizeof(mat_uint16_t))
1152 * @param data_type one of the @c matio_types enumerations which is the source
1153 * data type in the file
1154 * @param len Number of elements of type @c data_type to read from the file
1155 * @retval Number of bytes read from the file
1156 */
1157 int
ReadUInt16Data(mat_t * mat,mat_uint16_t * data,enum matio_types data_type,int len)1158 ReadUInt16Data(mat_t *mat,mat_uint16_t *data,enum matio_types data_type,int len)
1159 {
1160 int bytesread = 0, i, j;
1161 size_t data_size;
1162
1163 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
1164 return 0;
1165
1166 data_size = Mat_SizeOf(data_type);
1167 READ_DATA_TYPE(mat_uint16_t);
1168 bytesread *= data_size;
1169 return bytesread;
1170 }
1171
1172 #if defined(HAVE_ZLIB)
1173 /** @brief Reads data of type @c data_type into an unsigned 16-bit integer type
1174 *
1175 * Reads from the MAT file @c len compressed elements of data type @c data_type
1176 * storing them as unsigned 16-bit integers in @c data.
1177 * @ingroup mat_internal
1178 * @param mat MAT file pointer
1179 * @param z Pointer to the zlib stream for inflation
1180 * @param data Pointer to store the output n unsigned 16-bit integer values
1181 * (len*sizeof(mat_uint16_t))
1182 * @param data_type one of the @c matio_types enumerations which is the source
1183 * data type in the file
1184 * @param len Number of elements of type @c data_type to read from the file
1185 * @retval Number of bytes read from the file
1186 */
1187 int
ReadCompressedUInt16Data(mat_t * mat,z_streamp z,mat_uint16_t * data,enum matio_types data_type,int len)1188 ReadCompressedUInt16Data(mat_t *mat,z_streamp z,mat_uint16_t *data,
1189 enum matio_types data_type,int len)
1190 {
1191 int nBytes = 0, i;
1192 unsigned int data_size;
1193
1194 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1195 return 0;
1196
1197 data_size = (unsigned int)Mat_SizeOf(data_type);
1198 READ_COMPRESSED_DATA_TYPE(mat_uint16_t);
1199 nBytes = len*data_size;
1200 return nBytes;
1201 }
1202 #endif
1203
1204 /** @brief Reads data of type @c data_type into a signed 8-bit integer type
1205 *
1206 * Reads from the MAT file @c len elements of data type @c data_type storing
1207 * them as signed 8-bit integers in @c data.
1208 * @ingroup mat_internal
1209 * @param mat MAT file pointer
1210 * @param data Pointer to store the output signed 8-bit integer values
1211 * (len*sizeof(mat_int8_t))
1212 * @param data_type one of the @c matio_types enumerations which is the source
1213 * data type in the file
1214 * @param len Number of elements of type @c data_type to read from the file
1215 * @retval Number of bytes read from the file
1216 */
1217 int
ReadInt8Data(mat_t * mat,mat_int8_t * data,enum matio_types data_type,int len)1218 ReadInt8Data(mat_t *mat,mat_int8_t *data,enum matio_types data_type,int len)
1219 {
1220 int bytesread = 0, i, j;
1221 size_t data_size;
1222
1223 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
1224 return 0;
1225
1226 data_size = Mat_SizeOf(data_type);
1227 READ_DATA_TYPE(mat_int8_t);
1228 bytesread *= data_size;
1229 return bytesread;
1230 }
1231
1232 #if defined(HAVE_ZLIB)
1233 /** @brief Reads data of type @c data_type into a signed 8-bit integer type
1234 *
1235 * Reads from the MAT file @c len compressed elements of data type @c data_type
1236 * storing them as signed 8-bit integers in @c data.
1237 * @ingroup mat_internal
1238 * @param mat MAT file pointer
1239 * @param z Pointer to the zlib stream for inflation
1240 * @param data Pointer to store the output signed 8-bit integer values
1241 * (len*sizeof(mat_int8_t))
1242 * @param data_type one of the @c matio_types enumerations which is the source
1243 * data type in the file
1244 * @param len Number of elements of type @c data_type to read from the file
1245 * @retval Number of bytes read from the file
1246 */
1247 int
ReadCompressedInt8Data(mat_t * mat,z_streamp z,mat_int8_t * data,enum matio_types data_type,int len)1248 ReadCompressedInt8Data(mat_t *mat,z_streamp z,mat_int8_t *data,
1249 enum matio_types data_type,int len)
1250 {
1251 int nBytes = 0, i;
1252 unsigned int data_size;
1253
1254 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1255 return 0;
1256
1257 data_size = (unsigned int)Mat_SizeOf(data_type);
1258 READ_COMPRESSED_DATA_TYPE(mat_int8_t);
1259 nBytes = len*data_size;
1260 return nBytes;
1261 }
1262 #endif
1263
1264 /** @brief Reads data of type @c data_type into an unsigned 8-bit integer type
1265 *
1266 * Reads from the MAT file @c len elements of data type @c data_type storing
1267 * them as unsigned 8-bit integers in @c data.
1268 * @ingroup mat_internal
1269 * @param mat MAT file pointer
1270 * @param data Pointer to store the output unsigned 8-bit integer values
1271 * (len*sizeof(mat_uint8_t))
1272 * @param data_type one of the @c matio_types enumerations which is the source
1273 * data type in the file
1274 * @param len Number of elements of type @c data_type to read from the file
1275 * @retval Number of bytes read from the file
1276 */
1277 int
ReadUInt8Data(mat_t * mat,mat_uint8_t * data,enum matio_types data_type,int len)1278 ReadUInt8Data(mat_t *mat,mat_uint8_t *data,enum matio_types data_type,int len)
1279 {
1280 int bytesread = 0, i, j;
1281 size_t data_size;
1282
1283 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
1284 return 0;
1285
1286 data_size = Mat_SizeOf(data_type);
1287 READ_DATA_TYPE(mat_uint8_t);
1288 bytesread *= data_size;
1289 return bytesread;
1290 }
1291
1292 #if defined(HAVE_ZLIB)
1293 /** @brief Reads data of type @c data_type into an unsigned 8-bit integer type
1294 *
1295 * Reads from the MAT file @c len compressed elements of data type @c data_type
1296 * storing them as unsigned 8-bit integers in @c data.
1297 * @ingroup mat_internal
1298 * @param mat MAT file pointer
1299 * @param z Pointer to the zlib stream for inflation
1300 * @param data Pointer to store the output 8-bit integer values
1301 * (len*sizeof(mat_uint8_t))
1302 * @param data_type one of the @c matio_types enumerations which is the source
1303 * data type in the file
1304 * @param len Number of elements of type @c data_type to read from the file
1305 * @retval Number of bytes read from the file
1306 */
1307 int
ReadCompressedUInt8Data(mat_t * mat,z_streamp z,mat_uint8_t * data,enum matio_types data_type,int len)1308 ReadCompressedUInt8Data(mat_t *mat,z_streamp z,mat_uint8_t *data,
1309 enum matio_types data_type,int len)
1310 {
1311 int nBytes = 0, i;
1312 unsigned int data_size;
1313
1314 if ( (mat == NULL) || (data == NULL) || (z == NULL) )
1315 return 0;
1316
1317 data_size = (unsigned int)Mat_SizeOf(data_type);
1318 READ_COMPRESSED_DATA_TYPE(mat_uint8_t);
1319 nBytes = len*data_size;
1320 return nBytes;
1321 }
1322 #endif
1323
1324 #undef READ_DATA
1325 #undef READ_DATA_TYPE
1326 #undef READ_DATA_INT64
1327 #undef READ_DATA_UINT64
1328 #if defined(HAVE_ZLIB)
1329 #undef READ_COMPRESSED_DATA
1330 #undef READ_COMPRESSED_DATA_TYPE
1331 #undef READ_COMPRESSED_DATA_INT64
1332 #undef READ_COMPRESSED_DATA_UINT64
1333 #endif
1334 #if defined(HAVE_ZLIB)
1335 /** @brief Reads data of type @c data_type into a char type
1336 *
1337 * Reads from the MAT file @c len compressed elements of data type @c data_type
1338 * storing them as char's in @c data.
1339 * @ingroup mat_internal
1340 * @param mat MAT file pointer
1341 * @param z Pointer to the zlib stream for inflation
1342 * @param data Pointer to store the output char values (len*sizeof(char))
1343 * @param data_type one of the @c matio_types enumerations which is the source
1344 * data type in the file
1345 * @param len Number of elements of type @c data_type to read from the file
1346 * @retval Number of bytes read from the file
1347 */
1348 int
ReadCompressedCharData(mat_t * mat,z_streamp z,char * data,enum matio_types data_type,int len)1349 ReadCompressedCharData(mat_t *mat,z_streamp z,char *data,
1350 enum matio_types data_type,int len)
1351 {
1352 int nBytes = 0;
1353 unsigned int data_size;
1354
1355 if ( mat == NULL || data == NULL || mat->fp == NULL )
1356 return 0;
1357
1358 data_size = (unsigned int)Mat_SizeOf(data_type);
1359
1360 switch ( data_type ) {
1361 case MAT_T_UINT8:
1362 case MAT_T_UTF8:
1363 InflateData(mat,z,data,len*data_size);
1364 break;
1365 case MAT_T_UINT16:
1366 case MAT_T_UTF16:
1367 InflateData(mat,z,data,len*data_size);
1368 if ( mat->byteswap ) {
1369 int i;
1370 for ( i = 0; i < len; i++ ) {
1371 Mat_uint16Swap((mat_uint16_t*)&data[2*i]);
1372 }
1373 }
1374 break;
1375 default:
1376 Mat_Warning("ReadCompressedCharData: %d is not a supported data "
1377 "type for character data", data_type);
1378 break;
1379 }
1380 nBytes = len*data_size;
1381 return nBytes;
1382 }
1383 #endif
1384
1385 int
ReadCharData(mat_t * mat,char * data,enum matio_types data_type,int len)1386 ReadCharData(mat_t *mat,char *data,enum matio_types data_type,int len)
1387 {
1388 int bytesread = 0;
1389 size_t data_size;
1390
1391 if ( mat == NULL || data == NULL || mat->fp == NULL )
1392 return 0;
1393
1394 data_size = Mat_SizeOf(data_type);
1395
1396 switch ( data_type ) {
1397 case MAT_T_UINT8:
1398 case MAT_T_UTF8:
1399 bytesread += fread(data,data_size,len,(FILE*)mat->fp);
1400 break;
1401 case MAT_T_UINT16:
1402 case MAT_T_UTF16:
1403 {
1404 mat_uint16_t ui16;
1405 int i;
1406 if ( mat->byteswap ) {
1407 for ( i = 0; i < len; i++ ) {
1408 bytesread += fread(&ui16,data_size,1,(FILE*)mat->fp);
1409 data[i] = (char)Mat_uint16Swap(&ui16);
1410 }
1411 } else {
1412 for ( i = 0; i < len; i++ ) {
1413 bytesread += fread(&ui16,data_size,1,(FILE*)mat->fp);
1414 data[i] = (char)ui16;
1415 }
1416 }
1417 break;
1418 }
1419 default:
1420 Mat_Warning("ReadCharData: %d is not a supported data type for "
1421 "character data", data_type);
1422 break;
1423 }
1424 return bytesread;
1425 }
1426
1427 /*
1428 *-------------------------------------------------------------------
1429 * Routines to read "slabs" of data
1430 *-------------------------------------------------------------------
1431 */
1432
1433 #define READ_DATA_SLABN_RANK_LOOP \
1434 do { \
1435 for ( j = 1; j < rank; j++ ) { \
1436 cnt[j]++; \
1437 if ( (cnt[j] % edge[j]) == 0 ) { \
1438 cnt[j] = 0; \
1439 if ( (I % dimp[j]) != 0 ) { \
1440 (void)fseek((FILE*)mat->fp,data_size*(dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]),SEEK_CUR); \
1441 I += dimp[j]-(I % dimp[j]) + (ptrdiff_t)dimp[j-1]*start[j]; \
1442 } else if ( start[j] ) { \
1443 (void)fseek((FILE*)mat->fp,data_size*(dimp[j-1]*start[j]),SEEK_CUR); \
1444 I += (ptrdiff_t)dimp[j-1]*start[j]; \
1445 } \
1446 } else { \
1447 I += inc[j]; \
1448 (void)fseek((FILE*)mat->fp,data_size*inc[j],SEEK_CUR); \
1449 break; \
1450 } \
1451 } \
1452 } while (0)
1453
1454 #define READ_DATA_SLABN(ReadDataFunc) \
1455 do { \
1456 inc[0] = stride[0]-1; \
1457 dimp[0] = dims[0]; \
1458 N = edge[0]; \
1459 I = 0; /* start[0]; */ \
1460 for ( i = 1; i < rank; i++ ) { \
1461 inc[i] = stride[i]-1; \
1462 dimp[i] = dims[i-1]; \
1463 for ( j = i; j--; ) { \
1464 inc[i] *= dims[j]; \
1465 dimp[i] *= dims[j+1]; \
1466 } \
1467 N *= edge[i]; \
1468 I += (ptrdiff_t)dimp[i-1]*start[i]; \
1469 } \
1470 (void)fseek((FILE*)mat->fp,I*data_size,SEEK_CUR); \
1471 if ( stride[0] == 1 ) { \
1472 for ( i = 0; i < N; i+=edge[0] ) { \
1473 if ( start[0] ) { \
1474 (void)fseek((FILE*)mat->fp,start[0]*data_size,SEEK_CUR); \
1475 I += start[0]; \
1476 } \
1477 ReadDataFunc(mat,ptr+i,data_type,edge[0]); \
1478 I += dims[0]-start[0]; \
1479 (void)fseek((FILE*)mat->fp,data_size*(dims[0]-edge[0]-start[0]), \
1480 SEEK_CUR); \
1481 READ_DATA_SLABN_RANK_LOOP; \
1482 } \
1483 } else { \
1484 for ( i = 0; i < N; i+=edge[0] ) { \
1485 if ( start[0] ) { \
1486 (void)fseek((FILE*)mat->fp,start[0]*data_size,SEEK_CUR); \
1487 I += start[0]; \
1488 } \
1489 for ( j = 0; j < edge[0]; j++ ) { \
1490 ReadDataFunc(mat,ptr+i+j,data_type,1); \
1491 (void)fseek((FILE*)mat->fp,data_size*(stride[0]-1),SEEK_CUR); \
1492 I += stride[0]; \
1493 } \
1494 I += dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]; \
1495 (void)fseek((FILE*)mat->fp,data_size* \
1496 (dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]),SEEK_CUR); \
1497 READ_DATA_SLABN_RANK_LOOP; \
1498 } \
1499 } \
1500 } while (0)
1501
1502 /** @brief Reads data of type @c data_type by user-defined dimensions
1503 *
1504 * @ingroup mat_internal
1505 * @param mat MAT file pointer
1506 * @param data Pointer to store the output data
1507 * @param class_type Type of data class (matio_classes enumerations)
1508 * @param data_type Datatype of the stored data (matio_types enumerations)
1509 * @param rank Number of dimensions in the data
1510 * @param dims Dimensions of the data
1511 * @param start Index to start reading data in each dimension
1512 * @param stride Read every @c stride elements in each dimension
1513 * @param edge Number of elements to read in each dimension
1514 * @retval Number of bytes read from the file, or -1 on error
1515 */
1516 int
ReadDataSlabN(mat_t * mat,void * data,enum matio_classes class_type,enum matio_types data_type,int rank,size_t * dims,int * start,int * stride,int * edge)1517 ReadDataSlabN(mat_t *mat,void *data,enum matio_classes class_type,
1518 enum matio_types data_type,int rank,size_t *dims,int *start,int *stride,
1519 int *edge)
1520 {
1521 int nBytes = 0, i, j, N, I = 0;
1522 int inc[10] = {0,}, cnt[10] = {0,}, dimp[10] = {0,};
1523 size_t data_size;
1524
1525 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) ||
1526 (start == NULL) || (stride == NULL) || (edge == NULL) ) {
1527 return -1;
1528 } else if ( rank > 10 ) {
1529 return -1;
1530 }
1531
1532 data_size = Mat_SizeOf(data_type);
1533
1534 switch ( class_type ) {
1535 case MAT_C_DOUBLE:
1536 {
1537 double *ptr = (double*)data;
1538 READ_DATA_SLABN(ReadDoubleData);
1539 break;
1540 }
1541 case MAT_C_SINGLE:
1542 {
1543 float *ptr = (float*)data;
1544 READ_DATA_SLABN(ReadSingleData);
1545 break;
1546 }
1547 #ifdef HAVE_MAT_INT64_T
1548 case MAT_C_INT64:
1549 {
1550 mat_int64_t *ptr = (mat_int64_t*)data;
1551 READ_DATA_SLABN(ReadInt64Data);
1552 break;
1553 }
1554 #endif /* HAVE_MAT_INT64_T */
1555 #ifdef HAVE_MAT_UINT64_T
1556 case MAT_C_UINT64:
1557 {
1558 mat_uint64_t *ptr = (mat_uint64_t*)data;
1559 READ_DATA_SLABN(ReadUInt64Data);
1560 break;
1561 }
1562 #endif /* HAVE_MAT_UINT64_T */
1563 case MAT_C_INT32:
1564 {
1565 mat_int32_t *ptr = (mat_int32_t*)data;
1566 READ_DATA_SLABN(ReadInt32Data);
1567 break;
1568 }
1569 case MAT_C_UINT32:
1570 {
1571 mat_uint32_t *ptr = (mat_uint32_t*)data;
1572 READ_DATA_SLABN(ReadUInt32Data);
1573 break;
1574 }
1575 case MAT_C_INT16:
1576 {
1577 mat_int16_t *ptr = (mat_int16_t*)data;
1578 READ_DATA_SLABN(ReadInt16Data);
1579 break;
1580 }
1581 case MAT_C_UINT16:
1582 {
1583 mat_uint16_t *ptr = (mat_uint16_t*)data;
1584 READ_DATA_SLABN(ReadUInt16Data);
1585 break;
1586 }
1587 case MAT_C_INT8:
1588 {
1589 mat_int8_t *ptr = (mat_int8_t*)data;
1590 READ_DATA_SLABN(ReadInt8Data);
1591 break;
1592 }
1593 case MAT_C_UINT8:
1594 {
1595 mat_uint8_t *ptr = (mat_uint8_t*)data;
1596 READ_DATA_SLABN(ReadUInt8Data);
1597 break;
1598 }
1599 default:
1600 nBytes = 0;
1601 }
1602 return nBytes;
1603 }
1604
1605 #undef READ_DATA_SLABN
1606 #undef READ_DATA_SLABN_RANK_LOOP
1607
1608 #if defined(HAVE_ZLIB)
1609 #define READ_COMPRESSED_DATA_SLABN_RANK_LOOP \
1610 do { \
1611 for ( j = 1; j < rank; j++ ) { \
1612 cnt[j]++; \
1613 if ( (cnt[j] % edge[j]) == 0 ) { \
1614 cnt[j] = 0; \
1615 if ( (I % dimp[j]) != 0 ) { \
1616 InflateSkipData(mat,&z_copy,data_type, dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]); \
1617 I += dimp[j]-(I % dimp[j]) + (ptrdiff_t)dimp[j-1]*start[j]; \
1618 } else if ( start[j] ) { \
1619 InflateSkipData(mat,&z_copy,data_type, dimp[j-1]*start[j]); \
1620 I += (ptrdiff_t)dimp[j-1]*start[j]; \
1621 } \
1622 } else { \
1623 if ( inc[j] ) { \
1624 I += inc[j]; \
1625 InflateSkipData(mat,&z_copy,data_type,inc[j]); \
1626 } \
1627 break; \
1628 } \
1629 } \
1630 } while (0)
1631
1632 #define READ_COMPRESSED_DATA_SLABN(ReadDataFunc) \
1633 do { \
1634 inc[0] = stride[0]-1; \
1635 dimp[0] = dims[0]; \
1636 N = edge[0]; \
1637 I = 0; \
1638 for ( i = 1; i < rank; i++ ) { \
1639 inc[i] = stride[i]-1; \
1640 dimp[i] = dims[i-1]; \
1641 for ( j = i; j--; ) { \
1642 inc[i] *= dims[j]; \
1643 dimp[i] *= dims[j+1]; \
1644 } \
1645 N *= edge[i]; \
1646 I += (ptrdiff_t)dimp[i-1]*start[i]; \
1647 } \
1648 /* Skip all data to the starting indices */ \
1649 InflateSkipData(mat,&z_copy,data_type,I); \
1650 if ( stride[0] == 1 ) { \
1651 for ( i = 0; i < N; i+=edge[0] ) { \
1652 if ( start[0] ) { \
1653 InflateSkipData(mat,&z_copy,data_type,start[0]); \
1654 I += start[0]; \
1655 } \
1656 ReadDataFunc(mat,&z_copy,ptr+i,data_type,edge[0]); \
1657 InflateSkipData(mat,&z_copy,data_type,dims[0]-start[0]-edge[0]); \
1658 I += dims[0]-start[0]; \
1659 READ_COMPRESSED_DATA_SLABN_RANK_LOOP; \
1660 } \
1661 } else { \
1662 for ( i = 0; i < N; i+=edge[0] ) { \
1663 if ( start[0] ) { \
1664 InflateSkipData(mat,&z_copy,data_type,start[0]); \
1665 I += start[0]; \
1666 } \
1667 for ( j = 0; j < edge[0]-1; j++ ) { \
1668 ReadDataFunc(mat,&z_copy,ptr+i+j,data_type,1); \
1669 InflateSkipData(mat,&z_copy,data_type,(stride[0]-1)); \
1670 I += stride[0]; \
1671 } \
1672 ReadDataFunc(mat,&z_copy,ptr+i+j,data_type,1); \
1673 I += dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-start[0]; \
1674 InflateSkipData(mat,&z_copy,data_type,dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-start[0]-1); \
1675 READ_COMPRESSED_DATA_SLABN_RANK_LOOP; \
1676 } \
1677 } \
1678 } while (0)
1679
1680 /** @brief Reads data of type @c data_type by user-defined dimensions
1681 *
1682 * @ingroup mat_internal
1683 * @param mat MAT file pointer
1684 * @param z zlib compression stream
1685 * @param data Pointer to store the output data
1686 * @param class_type Type of data class (matio_classes enumerations)
1687 * @param data_type Datatype of the stored data (matio_types enumerations)
1688 * @param rank Number of dimensions in the data
1689 * @param dims Dimensions of the data
1690 * @param start Index to start reading data in each dimension
1691 * @param stride Read every @c stride elements in each dimension
1692 * @param edge Number of elements to read in each dimension
1693 * @retval Number of bytes read from the file, or -1 on error
1694 */
1695 int
ReadCompressedDataSlabN(mat_t * mat,z_streamp z,void * data,enum matio_classes class_type,enum matio_types data_type,int rank,size_t * dims,int * start,int * stride,int * edge)1696 ReadCompressedDataSlabN(mat_t *mat,z_streamp z,void *data,
1697 enum matio_classes class_type,enum matio_types data_type,int rank,
1698 size_t *dims,int *start,int *stride,int *edge)
1699 {
1700 int nBytes = 0, i, j, N, I = 0;
1701 int inc[10] = {0,}, cnt[10] = {0,}, dimp[10] = {0,};
1702 z_stream z_copy = {0,};
1703
1704 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) ||
1705 (start == NULL) || (stride == NULL) || (edge == NULL) ) {
1706 return 1;
1707 } else if ( rank > 10 ) {
1708 return 1;
1709 }
1710
1711 i = inflateCopy(&z_copy,z);
1712 switch ( class_type ) {
1713 case MAT_C_DOUBLE:
1714 {
1715 double *ptr = (double*)data;
1716 READ_COMPRESSED_DATA_SLABN(ReadCompressedDoubleData);
1717 break;
1718 }
1719 case MAT_C_SINGLE:
1720 {
1721 float *ptr = (float*)data;
1722 READ_COMPRESSED_DATA_SLABN(ReadCompressedSingleData);
1723 break;
1724 }
1725 #ifdef HAVE_MAT_INT64_T
1726 case MAT_C_INT64:
1727 {
1728 mat_int64_t *ptr = (mat_int64_t*)data;
1729 READ_COMPRESSED_DATA_SLABN(ReadCompressedInt64Data);
1730 break;
1731 }
1732 #endif /* HAVE_MAT_INT64_T */
1733 #ifdef HAVE_MAT_UINT64_T
1734 case MAT_C_UINT64:
1735 {
1736 mat_uint64_t *ptr = (mat_uint64_t*)data;
1737 READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt64Data);
1738 break;
1739 }
1740 #endif /* HAVE_MAT_UINT64_T */
1741 case MAT_C_INT32:
1742 {
1743 mat_int32_t *ptr = (mat_int32_t*)data;
1744 READ_COMPRESSED_DATA_SLABN(ReadCompressedInt32Data);
1745 break;
1746 }
1747 case MAT_C_UINT32:
1748 {
1749 mat_uint32_t *ptr = (mat_uint32_t*)data;
1750 READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt32Data);
1751 break;
1752 }
1753 case MAT_C_INT16:
1754 {
1755 mat_int16_t *ptr = (mat_int16_t*)data;
1756 READ_COMPRESSED_DATA_SLABN(ReadCompressedInt16Data);
1757 break;
1758 }
1759 case MAT_C_UINT16:
1760 {
1761 mat_uint16_t *ptr = (mat_uint16_t*)data;
1762 READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt16Data);
1763 break;
1764 }
1765 case MAT_C_INT8:
1766 {
1767 mat_int8_t *ptr = (mat_int8_t*)data;
1768 READ_COMPRESSED_DATA_SLABN(ReadCompressedInt8Data);
1769 break;
1770 }
1771 case MAT_C_UINT8:
1772 {
1773 mat_uint8_t *ptr = (mat_uint8_t*)data;
1774 READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt8Data);
1775 break;
1776 }
1777 default:
1778 nBytes = 0;
1779 }
1780 inflateEnd(&z_copy);
1781 return nBytes;
1782 }
1783
1784 #undef READ_COMPRESSED_DATA_SLABN
1785 #undef READ_COMPRESSED_DATA_SLABN_RANK_LOOP
1786 #endif
1787
1788 #define READ_DATA_SLAB1(ReadDataFunc) \
1789 do { \
1790 if ( !stride ) { \
1791 bytesread+=ReadDataFunc(mat,ptr,data_type,edge); \
1792 } else { \
1793 for ( i = 0; i < edge; i++ ) { \
1794 bytesread+=ReadDataFunc(mat,ptr+i,data_type,1); \
1795 (void)fseek((FILE*)mat->fp,stride,SEEK_CUR); \
1796 } \
1797 } \
1798 } while (0)
1799
1800 /** @brief Reads data of type @c data_type by user-defined dimensions for 1-D
1801 * data
1802 *
1803 * @ingroup mat_internal
1804 * @param mat MAT file pointer
1805 * @param data Pointer to store the output data
1806 * @param class_type Type of data class (matio_classes enumerations)
1807 * @param data_type Datatype of the stored data (matio_types enumerations)
1808 * @param start Index to start reading data
1809 * @param stride Read every @c stride elements
1810 * @param edge Number of elements to read
1811 * @return Number of bytes read from the file, or -1 on error
1812 */
1813 int
ReadDataSlab1(mat_t * mat,void * data,enum matio_classes class_type,enum matio_types data_type,int start,int stride,int edge)1814 ReadDataSlab1(mat_t *mat,void *data,enum matio_classes class_type,
1815 enum matio_types data_type,int start,int stride,int edge)
1816 {
1817 int i;
1818 size_t data_size;
1819 int bytesread = 0;
1820
1821 data_size = Mat_SizeOf(data_type);
1822 (void)fseek((FILE*)mat->fp,start*data_size,SEEK_CUR);
1823 stride = data_size*(stride-1);
1824
1825 switch ( class_type ) {
1826 case MAT_C_DOUBLE:
1827 {
1828 double *ptr = (double*)data;
1829 READ_DATA_SLAB1(ReadDoubleData);
1830 break;
1831 }
1832 case MAT_C_SINGLE:
1833 {
1834 float *ptr = (float*)data;
1835 READ_DATA_SLAB1(ReadSingleData);
1836 break;
1837 }
1838 #ifdef HAVE_MAT_INT64_T
1839 case MAT_C_INT64:
1840 {
1841 mat_int64_t *ptr = (mat_int64_t*)data;
1842 READ_DATA_SLAB1(ReadInt64Data);
1843 break;
1844 }
1845 #endif /* HAVE_MAT_INT64_T */
1846 #ifdef HAVE_MAT_UINT64_T
1847 case MAT_C_UINT64:
1848 {
1849 mat_uint64_t *ptr = (mat_uint64_t*)data;
1850 READ_DATA_SLAB1(ReadUInt64Data);
1851 break;
1852 }
1853 #endif /* HAVE_MAT_UINT64_T */
1854 case MAT_C_INT32:
1855 {
1856 mat_int32_t *ptr = (mat_int32_t*)data;
1857 READ_DATA_SLAB1(ReadInt32Data);
1858 break;
1859 }
1860 case MAT_C_UINT32:
1861 {
1862 mat_uint32_t *ptr = (mat_uint32_t*)data;
1863 READ_DATA_SLAB1(ReadUInt32Data);
1864 break;
1865 }
1866 case MAT_C_INT16:
1867 {
1868 mat_int16_t *ptr = (mat_int16_t*)data;
1869 READ_DATA_SLAB1(ReadInt16Data);
1870 break;
1871 }
1872 case MAT_C_UINT16:
1873 {
1874 mat_uint16_t *ptr = (mat_uint16_t*)data;
1875 READ_DATA_SLAB1(ReadUInt16Data);
1876 break;
1877 }
1878 case MAT_C_INT8:
1879 {
1880 mat_int8_t *ptr = (mat_int8_t*)data;
1881 READ_DATA_SLAB1(ReadInt8Data);
1882 break;
1883 }
1884 case MAT_C_UINT8:
1885 {
1886 mat_uint8_t *ptr = (mat_uint8_t*)data;
1887 READ_DATA_SLAB1(ReadUInt8Data);
1888 break;
1889 }
1890 default:
1891 return 0;
1892 }
1893
1894 return bytesread;
1895 }
1896
1897 #undef READ_DATA_SLAB1
1898
1899 #define READ_DATA_SLAB2(ReadDataFunc) \
1900 do { \
1901 /* If stride[0] is 1 and stride[1] is 1, we are reading all of the */ \
1902 /* data so get rid of the loops. */ \
1903 if ( (stride[0] == 1 && edge[0] == dims[0]) && \
1904 (stride[1] == 1) ) { \
1905 ReadDataFunc(mat,ptr,data_type,(ptrdiff_t)edge[0]*edge[1]); \
1906 } else { \
1907 row_stride = (long)(stride[0]-1)*data_size; \
1908 col_stride = (long)stride[1]*dims[0]*data_size; \
1909 pos = ftell((FILE*)mat->fp); \
1910 if ( pos == -1L ) { \
1911 Mat_Critical("Couldn't determine file position"); \
1912 return -1; \
1913 } \
1914 (void)fseek((FILE*)mat->fp,(long)start[1]*dims[0]*data_size,SEEK_CUR); \
1915 for ( i = 0; i < edge[1]; i++ ) { \
1916 pos = ftell((FILE*)mat->fp); \
1917 if ( pos == -1L ) { \
1918 Mat_Critical("Couldn't determine file position"); \
1919 return -1; \
1920 } \
1921 (void)fseek((FILE*)mat->fp,(long)start[0]*data_size,SEEK_CUR); \
1922 for ( j = 0; j < edge[0]; j++ ) { \
1923 ReadDataFunc(mat,ptr++,data_type,1); \
1924 (void)fseek((FILE*)mat->fp,row_stride,SEEK_CUR); \
1925 } \
1926 pos2 = ftell((FILE*)mat->fp); \
1927 if ( pos2 == -1L ) { \
1928 Mat_Critical("Couldn't determine file position"); \
1929 return -1; \
1930 } \
1931 pos +=col_stride-pos2; \
1932 (void)fseek((FILE*)mat->fp,pos,SEEK_CUR); \
1933 } \
1934 } \
1935 } while (0)
1936
1937 /** @brief Reads data of type @c data_type by user-defined dimensions for 2-D
1938 * data
1939 *
1940 * @ingroup mat_internal
1941 * @param mat MAT file pointer
1942 * @param data Pointer to store the output data
1943 * @param class_type Type of data class (matio_classes enumerations)
1944 * @param data_type Datatype of the stored data (matio_types enumerations)
1945 * @param dims Dimensions of the data
1946 * @param start Index to start reading data in each dimension
1947 * @param stride Read every @c stride elements in each dimension
1948 * @param edge Number of elements to read in each dimension
1949 * @retval Number of bytes read from the file, or -1 on error
1950 */
1951 int
ReadDataSlab2(mat_t * mat,void * data,enum matio_classes class_type,enum matio_types data_type,size_t * dims,int * start,int * stride,int * edge)1952 ReadDataSlab2(mat_t *mat,void *data,enum matio_classes class_type,
1953 enum matio_types data_type,size_t *dims,int *start,int *stride,int *edge)
1954 {
1955 int nBytes = 0, data_size, i, j;
1956 long pos, row_stride, col_stride, pos2;
1957
1958 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) ||
1959 (start == NULL) || (stride == NULL) || (edge == NULL) ) {
1960 return 0;
1961 }
1962
1963 data_size = Mat_SizeOf(data_type);
1964
1965 switch ( class_type ) {
1966 case MAT_C_DOUBLE:
1967 {
1968 double *ptr = (double*)data;
1969 READ_DATA_SLAB2(ReadDoubleData);
1970 break;
1971 }
1972 case MAT_C_SINGLE:
1973 {
1974 float *ptr = (float*)data;
1975 READ_DATA_SLAB2(ReadSingleData);
1976 break;
1977 }
1978 #ifdef HAVE_MAT_INT64_T
1979 case MAT_C_INT64:
1980 {
1981 mat_int64_t *ptr = (mat_int64_t*)data;
1982 READ_DATA_SLAB2(ReadInt64Data);
1983 break;
1984 }
1985 #endif /* HAVE_MAT_INT64_T */
1986 #ifdef HAVE_MAT_UINT64_T
1987 case MAT_C_UINT64:
1988 {
1989 mat_uint64_t *ptr = (mat_uint64_t*)data;
1990 READ_DATA_SLAB2(ReadUInt64Data);
1991 break;
1992 }
1993 #endif /* HAVE_MAT_UINT64_T */
1994 case MAT_C_INT32:
1995 {
1996 mat_int32_t *ptr = (mat_int32_t*)data;
1997 READ_DATA_SLAB2(ReadInt32Data);
1998 break;
1999 }
2000 case MAT_C_UINT32:
2001 {
2002 mat_uint32_t *ptr = (mat_uint32_t*)data;
2003 READ_DATA_SLAB2(ReadUInt32Data);
2004 break;
2005 }
2006 case MAT_C_INT16:
2007 {
2008 mat_int16_t *ptr = (mat_int16_t*)data;
2009 READ_DATA_SLAB2(ReadInt16Data);
2010 break;
2011 }
2012 case MAT_C_UINT16:
2013 {
2014 mat_uint16_t *ptr = (mat_uint16_t*)data;
2015 READ_DATA_SLAB2(ReadUInt16Data);
2016 break;
2017 }
2018 case MAT_C_INT8:
2019 {
2020 mat_int8_t *ptr = (mat_int8_t*)data;
2021 READ_DATA_SLAB2(ReadInt8Data);
2022 break;
2023 }
2024 case MAT_C_UINT8:
2025 {
2026 mat_uint8_t *ptr = (mat_uint8_t*)data;
2027 READ_DATA_SLAB2(ReadUInt8Data);
2028 break;
2029 }
2030 default:
2031 nBytes = 0;
2032 }
2033 return nBytes;
2034 }
2035
2036 #undef READ_DATA_SLAB2
2037
2038 #if defined(HAVE_ZLIB)
2039 #define READ_COMPRESSED_DATA_SLAB1(ReadDataFunc) \
2040 do { \
2041 if ( !stride ) { \
2042 nBytes+=ReadDataFunc(mat,&z_copy,ptr,data_type,edge); \
2043 } else { \
2044 for ( i = 0; i < edge; i++ ) { \
2045 nBytes+=ReadDataFunc(mat,&z_copy,ptr+i,data_type,1); \
2046 InflateSkipData(mat,&z_copy,data_type,stride); \
2047 } \
2048 } \
2049 } while (0)
2050
2051 /** @brief Reads data of type @c data_type by user-defined dimensions for 1-D
2052 * data
2053 *
2054 * @ingroup mat_internal
2055 * @param mat MAT file pointer
2056 * @param z zlib compression stream
2057 * @param data Pointer to store the output data
2058 * @param class_type Type of data class (matio_classes enumerations)
2059 * @param data_type Datatype of the stored data (matio_types enumerations)
2060 * @param dims Dimensions of the data
2061 * @param start Index to start reading data in each dimension
2062 * @param stride Read every @c stride elements in each dimension
2063 * @param edge Number of elements to read in each dimension
2064 * @retval Number of bytes read from the file, or -1 on error
2065 */
2066 int
ReadCompressedDataSlab1(mat_t * mat,z_streamp z,void * data,enum matio_classes class_type,enum matio_types data_type,int start,int stride,int edge)2067 ReadCompressedDataSlab1(mat_t *mat,z_streamp z,void *data,
2068 enum matio_classes class_type,enum matio_types data_type,int start,
2069 int stride,int edge)
2070 {
2071 int nBytes = 0, i, err;
2072 z_stream z_copy = {0,};
2073
2074 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) )
2075 return 0;
2076
2077 stride--;
2078 err = inflateCopy(&z_copy,z);
2079 InflateSkipData(mat,&z_copy,data_type,start);
2080 switch ( class_type ) {
2081 case MAT_C_DOUBLE:
2082 {
2083 double *ptr = (double*)data;
2084 READ_COMPRESSED_DATA_SLAB1(ReadCompressedDoubleData);
2085 break;
2086 }
2087 case MAT_C_SINGLE:
2088 {
2089 float *ptr = (float*)data;
2090 READ_COMPRESSED_DATA_SLAB1(ReadCompressedSingleData);
2091 break;
2092 }
2093 #ifdef HAVE_MAT_INT64_T
2094 case MAT_C_INT64:
2095 {
2096 mat_int64_t *ptr = (mat_int64_t*)data;
2097 READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt64Data);
2098 break;
2099 }
2100 #endif /* HAVE_MAT_INT64_T */
2101 #ifdef HAVE_MAT_UINT64_T
2102 case MAT_C_UINT64:
2103 {
2104 mat_uint64_t *ptr = (mat_uint64_t*)data;
2105 READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt64Data);
2106 break;
2107 }
2108 #endif /* HAVE_MAT_UINT64_T */
2109 case MAT_C_INT32:
2110 {
2111 mat_int32_t *ptr = (mat_int32_t*)data;
2112 READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt32Data);
2113 break;
2114 }
2115 case MAT_C_UINT32:
2116 {
2117 mat_uint32_t *ptr = (mat_uint32_t*)data;
2118 READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt32Data);
2119 break;
2120 }
2121 case MAT_C_INT16:
2122 {
2123 mat_int16_t *ptr = (mat_int16_t*)data;
2124 READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt16Data);
2125 break;
2126 }
2127 case MAT_C_UINT16:
2128 {
2129 mat_uint16_t *ptr = (mat_uint16_t*)data;
2130 READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt16Data);
2131 break;
2132 }
2133 case MAT_C_INT8:
2134 {
2135 mat_int8_t *ptr = (mat_int8_t*)data;
2136 READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt8Data);
2137 break;
2138 }
2139 case MAT_C_UINT8:
2140 {
2141 mat_uint8_t *ptr = (mat_uint8_t*)data;
2142 READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt8Data);
2143 break;
2144 }
2145 default:
2146 break;
2147 }
2148 inflateEnd(&z_copy);
2149 return nBytes;
2150 }
2151
2152 #undef READ_COMPRESSED_DATA_SLAB1
2153
2154 #define READ_COMPRESSED_DATA_SLAB2(ReadDataFunc) \
2155 do {\
2156 row_stride = (stride[0]-1); \
2157 col_stride = (stride[1]-1)*dims[0]; \
2158 InflateSkipData(mat,&z_copy,data_type,start[1]*dims[0]); \
2159 /* If stride[0] is 1 and stride[1] is 1, we are reading all of the */ \
2160 /* data so get rid of the loops. If stride[0] is 1 and stride[1] */ \
2161 /* is not 0, we are reading whole columns, so get rid of inner loop */ \
2162 /* to speed up the code */ \
2163 if ( (stride[0] == 1 && edge[0] == dims[0]) && \
2164 (stride[1] == 1) ) { \
2165 ReadDataFunc(mat,&z_copy,ptr,data_type,(ptrdiff_t)edge[0]*edge[1]); \
2166 } else if ( stride[0] == 1 ) { \
2167 for ( i = 0; i < edge[1]; i++ ) { \
2168 InflateSkipData(mat,&z_copy,data_type,start[0]); \
2169 ReadDataFunc(mat,&z_copy,ptr,data_type,edge[0]); \
2170 ptr += edge[0]; \
2171 pos = dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-1-start[0] + col_stride; \
2172 InflateSkipData(mat,&z_copy,data_type,pos); \
2173 } \
2174 } else { \
2175 for ( i = 0; i < edge[1]; i++ ) { \
2176 InflateSkipData(mat,&z_copy,data_type,start[0]); \
2177 for ( j = 0; j < edge[0]-1; j++ ) { \
2178 ReadDataFunc(mat,&z_copy,ptr++,data_type,1); \
2179 InflateSkipData(mat,&z_copy,data_type,row_stride); \
2180 } \
2181 ReadDataFunc(mat,&z_copy,ptr++,data_type,1); \
2182 pos = dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-1-start[0] + col_stride; \
2183 InflateSkipData(mat,&z_copy,data_type,pos); \
2184 } \
2185 } \
2186 } while (0)
2187
2188 /** @brief Reads data of type @c data_type by user-defined dimensions for 2-D
2189 * data
2190 *
2191 * @ingroup mat_internal
2192 * @param mat MAT file pointer
2193 * @param z zlib compression stream
2194 * @param data Pointer to store the output data
2195 * @param class_type Type of data class (matio_classes enumerations)
2196 * @param data_type Datatype of the stored data (matio_types enumerations)
2197 * @param dims Dimensions of the data
2198 * @param start Index to start reading data in each dimension
2199 * @param stride Read every @c stride elements in each dimension
2200 * @param edge Number of elements to read in each dimension
2201 * @retval Number of bytes read from the file, or -1 on error
2202 */
2203 int
ReadCompressedDataSlab2(mat_t * mat,z_streamp z,void * data,enum matio_classes class_type,enum matio_types data_type,size_t * dims,int * start,int * stride,int * edge)2204 ReadCompressedDataSlab2(mat_t *mat,z_streamp z,void *data,
2205 enum matio_classes class_type,enum matio_types data_type,size_t *dims,
2206 int *start,int *stride,int *edge)
2207 {
2208 int nBytes = 0, i, j, err;
2209 int pos, row_stride, col_stride;
2210 z_stream z_copy = {0,};
2211
2212 if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) ||
2213 (start == NULL) || (stride == NULL) || (edge == NULL) ) {
2214 return 0;
2215 }
2216
2217 err = inflateCopy(&z_copy,z);
2218 switch ( class_type ) {
2219 case MAT_C_DOUBLE:
2220 {
2221 double *ptr = (double*)data;
2222 READ_COMPRESSED_DATA_SLAB2(ReadCompressedDoubleData);
2223 break;
2224 }
2225 case MAT_C_SINGLE:
2226 {
2227 float *ptr = (float*)data;
2228 READ_COMPRESSED_DATA_SLAB2(ReadCompressedSingleData);
2229 break;
2230 }
2231 #ifdef HAVE_MAT_INT64_T
2232 case MAT_C_INT64:
2233 {
2234 mat_int64_t *ptr = (mat_int64_t*)data;
2235 READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt64Data);
2236 break;
2237 }
2238 #endif /* HAVE_MAT_INT64_T */
2239 #ifdef HAVE_MAT_UINT64_T
2240 case MAT_C_UINT64:
2241 {
2242 mat_uint64_t *ptr = (mat_uint64_t*)data;
2243 READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt64Data);
2244 break;
2245 }
2246 #endif /* HAVE_MAT_UINT64_T */
2247 case MAT_C_INT32:
2248 {
2249 mat_int32_t *ptr = (mat_int32_t*)data;
2250 READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt32Data);
2251 break;
2252 }
2253 case MAT_C_UINT32:
2254 {
2255 mat_uint32_t *ptr = (mat_uint32_t*)data;
2256 READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt32Data);
2257 break;
2258 }
2259 case MAT_C_INT16:
2260 {
2261 mat_int16_t *ptr = (mat_int16_t*)data;
2262 READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt16Data);
2263 break;
2264 }
2265 case MAT_C_UINT16:
2266 {
2267 mat_uint16_t *ptr = (mat_uint16_t*)data;
2268 READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt16Data);
2269 break;
2270 }
2271 case MAT_C_INT8:
2272 {
2273 mat_int8_t *ptr = (mat_int8_t*)data;
2274 READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt8Data);
2275 break;
2276 }
2277 case MAT_C_UINT8:
2278 {
2279 mat_uint8_t *ptr = (mat_uint8_t*)data;
2280 READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt8Data);
2281 break;
2282 }
2283 default:
2284 nBytes = 0;
2285 }
2286 inflateEnd(&z_copy);
2287 return nBytes;
2288 }
2289
2290 #undef READ_COMPRESSED_DATA_SLAB2
2291 #endif
2292
2293 /** @endcond */
2294