1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF. The full HDF copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /* $Id$ */
15
16 /*
17 FILE
18 hcomp.c
19 HDF compressed data I/O routines
20
21 REMARKS
22 These functions read and write compressed data to HDF data objects.
23 The compressed data objects are implemented as "special tags"
24 in the HDF file and the "H" layer I/O routines break out to the
25 functions in this module to deal with them.
26
27 DESIGN
28 The compression I/O functions are designed as state machines.
29 There are two seperate state machines implemented, as layers
30 on top of one another.
31 The top layer is the modeling layer,
32 whose purpose is to send/receive uncompressed bytes between the higher
33 layer (the "H" layer routines) and the lower layer, the coding layer.
34 The modeling layer is constrained to look like Standard C
35 I/O functions to the upper layer, while sending data in
36 potentially unusual orders to the coding layer. [An unusual
37 order of bytes would be a Peano or Hilbert curve instead
38 of the raster order more normally used].
39 The lower layer is the coding layer, whose purpose is to
40 send/receive bytes of data to the higher layer (the modeling
41 layer) and to send/receive bits/bytes of data to the bit I/O
42 functions after encoding them with some compression scheme.
43 Both of these layers are designed as independent state
44 machines whose state contains all the information to restart
45 at a given point. The purpose of this is to "cache" the
46 state of each layer at certain [convenient] times in order
47 to increase performance during random I/O.
48
49 BUGS/LIMITATIONS
50 Currently the following design limitations are still in place:
51 1 - Cannot compress an existing data element (will be fixed
52 before release) [ I think this is done, but it needs
53 testing]
54
55 2 - Statistic gathering from several types of compression
56 is not implemented (should be fixed before release)
57 3 - "State caching" for improved performance in not implemented,
58 although some data-structures allow for it. (should be
59 fixed before release)
60 4 - Random writing in compressed data is not supported (unlikely
61 to _ever_ be fixed)
62
63 EXPORTED ROUTINES
64 HCcreate - create or modify an existing data element to be compressed
65 LOCAL ROUTINES
66
67 AUTHOR
68 Quincey Koziol
69
70 MODIFICATION HISTORY
71 9/21/93 - Starting writing specs & coding prototype
72 10/09/93 - Finished initial testing. First version with only stdio
73 modeling and RLE coding done.
74 */
75
76 /* General HDF includes */
77 #define COMPRESS_MASTER
78 #include "hdf.h"
79
80 #ifdef H4_HAVE_LIBSZ
81 #include "szlib.h"
82 #endif
83
84 /* HDF compression includes */
85 #include "hcompi.h" /* Internal definitions for compression */
86
87 /* Local defines */
88 #define COMP_HEADER_VERSION 0
89 #ifdef OLD_WAY
90 #define COMP_START_BLOCK 1
91 #else /* OLD_WAY */
92 #define COMP_START_BLOCK 0
93 #endif /* OLD_WAY */
94
95 /* declaration of the functions provided in this module */
96 PRIVATE int32 HCIstaccess
97 (accrec_t * access_rec, int16 acc_mode);
98
99 PRIVATE int32 HCIinit_coder
100 (int16 acc_mode, comp_coder_info_t * cinfo, comp_coder_t coder_type,
101 comp_info * coder_info);
102
103 PRIVATE int32 HCIread_header
104 (accrec_t * access_rec, compinfo_t * info,
105 comp_info * c_info, model_info * m_info);
106
107 PRIVATE int32 HCIwrite_header
108 (atom_t file_id, compinfo_t * info, uint16 special_tag, uint16 ref,
109 comp_info *c_info, model_info *m_info);
110
111 PRIVATE int32 HCIinit_model
112 (int16 acc_mode, comp_model_info_t * minfo, comp_model_t model_type,
113 model_info * m_info);
114
115 /* comp_funcs -- struct of accessing functions for the compressed
116 data element function modules. The position of each function in
117 the table is standard */
118
119 funclist_t comp_funcs =
120 {
121 HCPstread,
122 HCPstwrite,
123 HCPseek,
124 HCPinquire,
125 HCPread,
126 HCPwrite,
127 HCPendaccess,
128 HCPinfo,
129 NULL /* no routine registerd */
130 };
131
132 /* #define TESTING */
133
134 /*--------------------------------------------------------------------------
135 NAME
136 HCIinit_coder -- Set the coder function pointers
137 USAGE
138 int32 HCIinit_coder(cinfo,coder_type,coder_info)
139 comp_coder_info_t *cinfo; IN/OUT: pointer to coder information to modify
140 comp_coder_t coder_type; IN: the type of encoding to use
141 comp_info *coder_info; IN: setup information for some encoding types
142
143 RETURNS
144 Return SUCCEED or FAIL
145 DESCRIPTION
146 Sets the encoder function pointers and the encoder type for a given
147 coder type.
148
149 GLOBAL VARIABLES
150 COMMENTS, BUGS, ASSUMPTIONS
151 IMCOMP: Since IMCOMP is no longer supported in creating new data but the
152 library still reads existing data, it may need to be added into
153 this function somehow. Yet, I'm not sure exactly how it should
154 be added because this function is called in both cases, writing
155 and reading. At this time, the function will fail if it encounters
156 COMP_CODE_IMCOMP. -BMR, Jul 11, 2012
157 EXAMPLES
158 REVISION LOG
159 --------------------------------------------------------------------------*/
160 PRIVATE int32
HCIinit_coder(int16 acc_mode,comp_coder_info_t * cinfo,comp_coder_t coder_type,comp_info * c_info)161 HCIinit_coder(int16 acc_mode, comp_coder_info_t * cinfo, comp_coder_t coder_type,
162 comp_info * c_info)
163 {
164 uint32 comp_info;
165 CONSTR(FUNC, "HCIinit_coder"); /* for HERROR */
166
167 HCget_config_info(coder_type, &comp_info);
168 /* TODO: This construct S.B.
169 * (comp_info & (COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED))
170 * but the calling code does not handle it correctly
171 */
172 if ((comp_info & COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED) == 0) {
173 /* coder not present?? */
174 HRETURN_ERROR(DFE_BADCODER, FAIL)
175 }
176
177 switch (coder_type)
178 { /* determine the type of encoding */
179 case COMP_CODE_NONE: /* "none" (i.e. no) encoding */
180 cinfo->coder_type = COMP_CODE_NONE; /* set coding type */
181 cinfo->coder_funcs = cnone_funcs; /* set the "none" func. ptrs */
182 break;
183
184 case COMP_CODE_RLE: /* Run-length encoding */
185 cinfo->coder_type = COMP_CODE_RLE; /* set coding type */
186 cinfo->coder_funcs = crle_funcs; /* set the RLE func. ptrs */
187 break;
188
189 case COMP_CODE_NBIT: /* N-bit encoding */
190 cinfo->coder_type = COMP_CODE_NBIT; /* set the coding type */
191 cinfo->coder_funcs = cnbit_funcs; /* set the N-bit func. ptrs */
192
193 /* copy encoding info */
194 cinfo->coder_info.nbit_info.nt = c_info->nbit.nt;
195 cinfo->coder_info.nbit_info.sign_ext = c_info->nbit.sign_ext;
196 cinfo->coder_info.nbit_info.fill_one = c_info->nbit.fill_one;
197 cinfo->coder_info.nbit_info.mask_off = c_info->nbit.start_bit;
198 cinfo->coder_info.nbit_info.mask_len = c_info->nbit.bit_len;
199 if ((cinfo->coder_info.nbit_info.nt_size
200 = DFKNTsize(cinfo->coder_info.nbit_info.nt)) == FAIL)
201 HRETURN_ERROR(DFE_BADNUMTYPE, FAIL);
202 break;
203
204 case COMP_CODE_SKPHUFF: /* Skipping Huffman encoding */
205 if(c_info->skphuff.skp_size<1)
206 HRETURN_ERROR(DFE_BADCODER, FAIL)
207
208 /* set the coding type and the skipping huffman func. ptrs */
209 cinfo->coder_type = COMP_CODE_SKPHUFF;
210 cinfo->coder_funcs = cskphuff_funcs;
211
212 /* copy encoding info */
213 cinfo->coder_info.skphuff_info.skip_size = c_info->skphuff.skp_size;
214 break;
215
216 case COMP_CODE_DEFLATE: /* gzip 'deflate' encoding */
217 /* valid deflate levels are from 0 to 9, this error checking
218 caused the problem in HDF4r1.2 , fixed by Apu Kapadia
219 if(c_info->deflate.level<1 || c_info->deflate.level>9)
220 */
221 if(c_info->deflate.level<0 || c_info->deflate.level>9)
222 HRETURN_ERROR(DFE_BADCODER, FAIL)
223
224 /* set the coding type and the gzip 'deflate' func. ptrs */
225 cinfo->coder_type = COMP_CODE_DEFLATE;
226 cinfo->coder_funcs = cdeflate_funcs;
227
228 /* copy encoding info */
229 if(acc_mode&DFACC_WRITE)
230 cinfo->coder_info.deflate_info.deflate_level = c_info->deflate.level;
231 break;
232
233 case COMP_CODE_SZIP:
234 /* set the coding type */
235 cinfo->coder_type = COMP_CODE_SZIP;
236
237 /* when libsz presents, initialize other info - BMR, 08/25/2007
238 (changed from eliminating this case completely) */
239 /* completely removed the libsz limitation, we shouldn't need
240 szip library to initialize here - BMR, 10/21/2008 */
241
242 /* set the szip func. ptrs */
243 cinfo->coder_funcs = cszip_funcs;
244
245 /* copy encoding info */
246 cinfo->coder_info.szip_info.pixels = c_info->szip.pixels;
247 cinfo->coder_info.szip_info.bits_per_pixel = c_info->szip.bits_per_pixel;
248 cinfo->coder_info.szip_info.pixels_per_block = c_info->szip.pixels_per_block;
249 cinfo->coder_info.szip_info.pixels_per_scanline = c_info->szip.pixels_per_scanline;
250 cinfo->coder_info.szip_info.options_mask = c_info->szip.options_mask;
251 cinfo->coder_info.szip_info.buffer = NULL;
252 cinfo->coder_info.szip_info.buffer_size = 0;
253 cinfo->coder_info.szip_info.offset = 0;
254 cinfo->coder_info.szip_info.szip_state = SZIP_INIT;
255 cinfo->coder_info.szip_info.szip_dirty = SZIP_CLEAN;
256 break;
257
258 default:
259 HRETURN_ERROR(DFE_BADCODER, FAIL)
260 } /* end switch */
261 return (SUCCEED);
262 } /* end HCIinit_coder() */
263
264 /*--------------------------------------------------------------------------
265 NAME
266 HCIinit_model -- Set the model function pointers
267 USAGE
268 int32 HCIinit_model(minfo,model_type,m_info)
269 comp_model_info_t *minfo; IN/OUT: pointer to model information to modify
270 comp_model_t model_type; IN: the type of encoding to use
271 model_info *m_info; IN: modeling information
272
273 RETURNS
274 Return SUCCEED or FAIL
275 DESCRIPTION
276 Sets the modeling function pointers and the model type for a given
277 model type.
278
279 GLOBAL VARIABLES
280 COMMENTS, BUGS, ASSUMPTIONS
281 EXAMPLES
282 REVISION LOG
283 --------------------------------------------------------------------------*/
284 PRIVATE int32
HCIinit_model(int16 acc_mode,comp_model_info_t * minfo,comp_model_t model_type,model_info * m_info)285 HCIinit_model(int16 acc_mode, comp_model_info_t * minfo, comp_model_t model_type,
286 model_info * m_info)
287 {
288 CONSTR(FUNC, "HCIinit_model"); /* for HERROR */
289
290 /* shut compiler up */
291 acc_mode = acc_mode;
292 m_info = m_info;
293
294 switch (model_type)
295 { /* determine the type of modeling */
296 case COMP_MODEL_STDIO: /* standard C stdio modeling */
297 minfo->model_type = COMP_MODEL_STDIO; /* set model type */
298 minfo->model_funcs = mstdio_funcs; /* set the stdio func. ptrs */
299 break;
300
301 default:
302 HRETURN_ERROR(DFE_BADMODEL, FAIL)
303 } /* end switch */
304
305 return (SUCCEED);
306 } /* end HCIinit_model() */
307
308 /*--------------------------------------------------------------------------
309 NAME
310 HCPquery_encode_header -- Query the length of compression header for a memory buffer
311 USAGE
312 int32 HCPquery_encode_header(model_type, model_info, coder_type, coder_info)
313 comp_model_t model_type; IN: the type of modeling to use
314 model_info *m_info; IN: Information needed for the modeling type chosen
315 comp_coder_t coder_type; IN: the type of encoding to use
316 coder_info *c_info; IN: Information needed for the encoding type chosen
317
318 RETURNS
319 Return the length of the buffer needed to store the compression header on
320 success (>0) or FAIL (-1)
321 DESCRIPTION
322 Determine the compression information length in a memory block.
323
324 GLOBAL VARIABLES
325 COMMENTS, BUGS, ASSUMPTIONS
326 EXAMPLES
327 REVISION LOG
328 --------------------------------------------------------------------------*/
329 int32
HCPquery_encode_header(comp_model_t model_type,model_info * m_info,comp_coder_t coder_type,comp_info * c_info)330 HCPquery_encode_header(comp_model_t model_type, model_info * m_info,
331 comp_coder_t coder_type, comp_info * c_info)
332 {
333 CONSTR(FUNC, "HCPquery_encode_header"); /* for HERROR */
334 int32 coder_len=2; /* # of bytes to encode coder information (2 minimum) */
335 int32 model_len=2; /* # of bytes to encode model information (2 minimum) */
336 int32 ret_value=SUCCEED;
337
338 /* clear error stack and validate args */
339 HEclear();
340 if (m_info==NULL || c_info==NULL)
341 HGOTO_ERROR(DFE_ARGS, FAIL);
342
343 /* add any additional information needed for modeling type */
344 switch (model_type)
345 {
346 default: /* no additional information needed */
347 break;
348 } /* end switch */
349
350 /* add any additional information needed for coding type */
351 switch (coder_type)
352 {
353 case COMP_CODE_NBIT: /* N-bit coding needs 16 bytes of info */
354 coder_len+=16;
355 break;
356
357 case COMP_CODE_SKPHUFF: /* Skipping Huffman coding needs 8 bytes of info */
358 coder_len+=8;
359 break;
360
361 case COMP_CODE_DEFLATE: /* Deflation coding stores deflation level */
362 coder_len+=2;
363 break;
364
365 case COMP_CODE_SZIP: /* Szip coding stores various szip parameters */
366 coder_len += 14;
367 break;
368
369 case COMP_CODE_IMCOMP: /* IMCOMP is no longer supported, can only be inquired */
370 HRETURN_ERROR(DFE_BADCODER, FAIL);
371 break;
372
373 default: /* no additional information needed */
374 break;
375 } /* end switch */
376
377 ret_value=model_len+coder_len;
378
379 done:
380 if(ret_value == FAIL)
381 { /* Error condition cleanup */
382
383 } /* end if */
384
385 /* Normal function cleanup */
386 return ret_value;
387 } /* end HCPquery_encode_header() */
388
389 /*--------------------------------------------------------------------------
390 NAME
391 HCPencode_header -- Encode the compression header info to a memory buffer
392 USAGE
393 intn HCPencode_header(model_type, model_info, coder_type, coder_info)
394 void * buf; OUT: encoded compression info header
395 comp_model_t model_type; IN: the type of modeling to use
396 model_info *m_info; IN: Information needed for the modeling type chosen
397 comp_coder_t coder_type; IN: the type of encoding to use
398 coder_info *c_info; IN: Information needed for the encoding type chosen
399
400 RETURNS
401 Return SUCCEED or FAIL
402 DESCRIPTION
403 Encodes the compression information to a block in memory.
404
405 GLOBAL VARIABLES
406 COMMENTS, BUGS, ASSUMPTIONS
407 EXAMPLES
408 REVISION LOG
409 --------------------------------------------------------------------------*/
410 intn
HCPencode_header(uint8 * p,comp_model_t model_type,model_info * m_info,comp_coder_t coder_type,comp_info * c_info)411 HCPencode_header(uint8 *p, comp_model_t model_type, model_info * m_info,
412 comp_coder_t coder_type, comp_info * c_info)
413 {
414 CONSTR(FUNC, "HCPencode_header"); /* for HERROR */
415 int32 ret_value=SUCCEED;
416
417 /* clear error stack and validate args */
418 HEclear();
419 if (p==NULL || m_info==NULL || c_info==NULL)
420 HGOTO_ERROR(DFE_ARGS, FAIL);
421
422 UINT16ENCODE(p, (uint16) model_type); /* specify model type */
423 UINT16ENCODE(p, (uint16) coder_type); /* specify coder type */
424
425 /* add any additional information needed for modeling type */
426 switch (model_type)
427 {
428 default: /* no additional information needed */
429 break;
430 } /* end switch */
431
432 /* add any additional information needed for coding type */
433 switch (coder_type)
434 {
435 case COMP_CODE_NBIT: /* N-bit coding needs info */
436 /* specify number-type of N-bit data */
437 INT32ENCODE(p, c_info->nbit.nt);
438 /* next is the flag to indicate whether to sign extend */
439 UINT16ENCODE(p, (uint16) c_info->nbit.sign_ext);
440 /* flag to fill with 1's or 0's */
441 UINT16ENCODE(p, (uint16) c_info->nbit.fill_one);
442 /* the offset of the bits extracted */
443 INT32ENCODE(p, (int32) c_info->nbit.start_bit);
444 /* the number of bits extracted */
445 INT32ENCODE(p, (int32) c_info->nbit.bit_len);
446 break;
447
448 case COMP_CODE_SKPHUFF: /* Skipping Huffman coding needs info */
449 if(c_info->skphuff.skp_size<1)
450 HRETURN_ERROR(DFE_BADCODER, FAIL)
451
452 /* specify skipping unit size */
453 UINT32ENCODE(p, (uint32) c_info->skphuff.skp_size);
454 /* specify # of bytes compressed (not used currently) */
455 UINT32ENCODE(p, (uint32) c_info->skphuff.skp_size);
456 break;
457
458 case COMP_CODE_DEFLATE: /* Deflation coding stores deflation level */
459 /* valid deflate levels are from 0 to 9
460 if(c_info->deflate.level<1 || c_info->deflate.level>9)
461 */
462 if(c_info->deflate.level<0 || c_info->deflate.level>9)
463 HRETURN_ERROR(DFE_BADCODER, FAIL)
464
465 /* specify deflation level */
466 UINT16ENCODE(p, (uint16) c_info->deflate.level);
467 break;
468
469 case COMP_CODE_SZIP: /* Szip coding stores various szip parameters */
470 UINT32ENCODE(p, (uint32) c_info->szip.pixels);
471 UINT32ENCODE(p, (uint32) c_info->szip.pixels_per_scanline);
472 UINT32ENCODE(p, (uint32) (c_info->szip.options_mask | SZ_H4_REV_2));
473 *p++ = (uint8) c_info->szip.bits_per_pixel;
474 *p++ = (uint8) c_info->szip.pixels_per_block;
475 break;
476
477 case COMP_CODE_IMCOMP: /* IMCOMP is no longer supported, can only be inquired */
478 HRETURN_ERROR(DFE_BADCODER, FAIL);
479 break;
480
481 default: /* no additional information needed */
482 break;
483 } /* end switch */
484
485 done:
486 if(ret_value == FAIL)
487 { /* Error condition cleanup */
488
489 } /* end if */
490
491 /* Normal function cleanup */
492 return ret_value;
493 } /* end HCPencode_header() */
494
495 /*--------------------------------------------------------------------------
496 NAME
497 HCPdecode_header -- Decode the compression header info from a memory buffer
498 USAGE
499 intn HCPdecode_header(model_type, model_info, coder_type, coder_info)
500 void * buf; IN: encoded compression info header
501 comp_model_t *model_type; OUT: the type of modeling to use
502 model_info *m_info; OUT: Information needed for the modeling type chosen
503 comp_coder_t *coder_type; OUT: the type of encoding to use
504 coder_info *c_info; OUT: Information needed for the encoding type chosen
505
506 RETURNS
507 Return SUCCEED or FAIL
508 DESCRIPTION
509 Decodes the compression information from a block in memory.
510
511 GLOBAL VARIABLES
512 COMMENTS, BUGS, ASSUMPTIONS
513 EXAMPLES
514 REVISION LOG
515 --------------------------------------------------------------------------*/
516 intn
HCPdecode_header(uint8 * p,comp_model_t * model_type,model_info * m_info,comp_coder_t * coder_type,comp_info * c_info)517 HCPdecode_header(uint8 *p, comp_model_t *model_type, model_info * m_info,
518 comp_coder_t *coder_type, comp_info * c_info)
519 {
520 CONSTR(FUNC, "HCPdecode_header"); /* for HERROR */
521 uint16 m_type, c_type;
522 int32 ret_value=SUCCEED;
523
524 /* clear error stack and validate args */
525 HEclear();
526 if (p==NULL || model_type==NULL || m_info==NULL || coder_type==NULL || c_info==NULL)
527 HGOTO_ERROR(DFE_ARGS, FAIL);
528
529 UINT16DECODE(p, m_type); /* get model type */
530 *model_type=(comp_model_t)m_type;
531 UINT16DECODE(p, c_type); /* get encoding type */
532 *coder_type=(comp_coder_t)c_type;
533
534 /* read any additional information needed for modeling type */
535 switch (*model_type)
536 {
537 default: /* no additional information needed */
538 break;
539 } /* end switch */
540
541 /* read any additional information needed for coding type */
542 switch (*coder_type)
543 {
544 case COMP_CODE_NBIT: /* Obtain info for N-bit coding */
545 {
546 uint16 s_ext; /* temp. var for sign extend */
547 uint16 f_one; /* temp. var for fill one */
548 int32 m_off, m_len; /* temp. var for mask offset and len */
549
550 /* number-type of N-bit data */
551 INT32DECODE(p, c_info->nbit.nt);
552 /* next is the flag to indicate whether to sign extend */
553 UINT16DECODE(p, s_ext);
554 c_info->nbit.sign_ext = (intn) s_ext;
555 /* flag to indicate whether to fill with 1's or 0's */
556 UINT16DECODE(p, f_one);
557 c_info->nbit.fill_one = (intn) f_one;
558 /* offset of the bits extracted */
559 INT32DECODE(p, m_off);
560 c_info->nbit.start_bit = (intn) m_off;
561 /* number of bits extracted */
562 INT32DECODE(p, m_len);
563 c_info->nbit.bit_len = (intn) m_len;
564 } /* end case */
565 break;
566
567 case COMP_CODE_SKPHUFF: /* Obtain info for Skipping Huffman coding */
568 {
569 uint32 skp_size, /* size of skipping unit */
570 comp_size; /* # of bytes to compress */
571
572 /* specify skipping unit size */
573 UINT32DECODE(p, skp_size);
574 /* specify # of bytes of skipping data to compress */
575 UINT32DECODE(p, comp_size); /* ignored for now */
576 c_info->skphuff.skp_size = (intn) skp_size;
577 } /* end case */
578 break;
579
580 case COMP_CODE_DEFLATE: /* Obtains deflation level for Deflation coding */
581 {
582 uint16 level; /* deflation level */
583
584 /* specify deflation level */
585 UINT16DECODE(p, level);
586 c_info->deflate.level = (intn) level;
587 } /* end case */
588 break;
589
590 case COMP_CODE_SZIP: /* Obtains szip parameters for Szip coding */
591 {
592 UINT32DECODE(p, c_info->szip.pixels);
593 UINT32DECODE(p, c_info->szip.pixels_per_scanline);
594 UINT32DECODE(p, c_info->szip.options_mask);
595 c_info->szip.bits_per_pixel = *p++;
596 c_info->szip.pixels_per_block = *p++;
597 }
598 break;
599
600 default: /* no additional information needed */
601 /* this includes RLE, JPEG, and IMCOMP */
602 break;
603 } /* end switch */
604
605 done:
606 if(ret_value == FAIL)
607 { /* Error condition cleanup */
608
609 } /* end if */
610
611 /* Normal function cleanup */
612 return ret_value;
613 } /* end HCPdecode_header() */
614
615 /*--------------------------------------------------------------------------
616 NAME
617 HCIwrite_header -- Write the compression header info to a file
618 USAGE
619 int32 HCIwrite_header(access_rec,info,special_tag,ref)
620 atom_t file_id; IN: File ID of the file to write the header to
621 compinfo_t *info; IN: ptr the compression information
622 uint16 special_tag,ref; IN: the tag/ref of the compressed element
623 coder_info *c_info; IN: Information needed for the encoding type chosen
624 model_info *m_info; IN: Information needed for the modeling type chosen
625
626 RETURNS
627 Return SUCCEED or FAIL
628 DESCRIPTION
629 Writes the compression information to a new block in the HDF file.
630
631 GLOBAL VARIABLES
632 COMMENTS, BUGS, ASSUMPTIONS
633 EXAMPLES
634 REVISION LOG
635 --------------------------------------------------------------------------*/
636 PRIVATE int32
HCIwrite_header(atom_t file_id,compinfo_t * info,uint16 special_tag,uint16 ref,comp_info * c_info,model_info * m_info)637 HCIwrite_header(atom_t file_id, compinfo_t * info, uint16 special_tag, uint16 ref, comp_info *c_info, model_info *m_info)
638 {
639 CONSTR(FUNC, "HCIwrite_header"); /* for HERROR */
640 int32 dd_aid; /* AID for writing the special info */
641 uint8 *p; /* pointer to the temporary buffer */
642 uint8 local_ptbuf[32];
643 int32 header_len; /* how many bytes the header is */
644 int32 ret_value=SUCCEED;
645
646 /* write special element info to the file */
647 p = local_ptbuf;
648 INT16ENCODE(p, SPECIAL_COMP); /* specify special tag type */
649 UINT16ENCODE(p, COMP_HEADER_VERSION); /* specify header version */
650 INT32ENCODE(p, info->length); /* write length of un-comp. data */
651 UINT16ENCODE(p, (uint16) info->comp_ref); /* specify ref # of comp. data */
652 #ifdef OLD_WAY
653 UINT16ENCODE(p, (uint16) info->minfo.model_type); /* specify model type */
654 UINT16ENCODE(p, (uint16) info->cinfo.coder_type); /* specify coder type */
655
656 /* write any additional information needed for modeling type */
657 switch (info->minfo.model_type)
658 {
659 default: /* no additional information needed */
660 break;
661 } /* end switch */
662
663 /* write any additional information needed for coding type */
664 switch (info->cinfo.coder_type)
665 {
666 case COMP_CODE_NBIT: /* N-bit coding needs info */
667 /* specify number-type of N-bit data */
668 INT32ENCODE(p, info->cinfo.coder_info.nbit_info.nt);
669 /* next is the flag to indicate whether to sign extend */
670 UINT16ENCODE(p, (uint16) info->cinfo.coder_info.nbit_info.sign_ext);
671 /* flag to fill with 1's or 0's */
672 UINT16ENCODE(p, (uint16) info->cinfo.coder_info.nbit_info.fill_one);
673 /* the offset of the bits extracted */
674 INT32ENCODE(p, (int32) info->cinfo.coder_info.nbit_info.mask_off);
675 /* the number of bits extracted */
676 INT32ENCODE(p, (int32) info->cinfo.coder_info.nbit_info.mask_len);
677 break;
678
679 case COMP_CODE_SKPHUFF: /* Skipping Huffman coding needs info */
680 /* specify skipping unit size */
681 UINT32ENCODE(p, (uint32) info->cinfo.coder_info.skphuff_info.skip_size);
682 /* specify # of bytes compressed (not used currently) */
683 UINT32ENCODE(p, (uint32) info->cinfo.coder_info.skphuff_info.skip_size);
684 break;
685
686 case COMP_CODE_SZIP:
687 INT32ENCODE(p, (int32) c_info->szip.pixels);
688 INT32ENCODE(p, (int32) c_info->szip.pixels_per_scanline);
689 INT32ENCODE(p, (int32) c_info->szip.options_mask);
690 INT32ENCODE(p, (int32) c_info->szip.bits_per_pixel);
691 INT32ENCODE(p, (int32) c_info->szip.pixels_per_block);
692 break;
693
694 case COMP_CODE_IMCOMP: /* IMCOMP is no longer supported, can only be inquired */
695 HRETURN_ERROR(DFE_BADCODER, FAIL);
696 break;
697
698 default: /* no additional information needed */
699 break;
700 } /* end switch */
701 #else /* OLD_WAY */
702 if((header_len=HCPquery_encode_header(info->minfo.model_type,
703 m_info,info->cinfo.coder_type,c_info))==FAIL)
704 HGOTO_ERROR(DFE_INTERNAL, FAIL);
705 if(HCPencode_header(p,info->minfo.model_type,m_info,
706 info->cinfo.coder_type,c_info)==FAIL)
707 HGOTO_ERROR(DFE_INTERNAL, FAIL);
708 p+=header_len;
709 #endif /* OLD_WAY */
710
711 /* write the special info structure to fill */
712 if((dd_aid=Hstartaccess(file_id,special_tag,ref,DFACC_ALL))==FAIL)
713 HGOTO_ERROR(DFE_CANTACCESS, FAIL);
714 if (Hwrite(dd_aid, p-local_ptbuf, local_ptbuf) == FAIL)
715 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
716 if(Hendaccess(dd_aid)==FAIL)
717 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
718
719 done:
720 if(ret_value == FAIL)
721 { /* Error condition cleanup */
722
723 } /* end if */
724
725 /* Normal function cleanup */
726 return ret_value;
727 } /* end HCIwrite_header() */
728
729 /*--------------------------------------------------------------------------
730 NAME
731 HCIread_header -- Read the compression header info from a file
732 USAGE
733 int32 HCIread_header(file_rec,access_rec,info,comp_info,model_info)
734 accrec_t *access_rec; IN: ptr to the access element record
735 compinfo_t *info; IN: ptr the compression information
736 comp_info *comp_info; IN/OUT: ptr to encoding info
737 model_info *model_info; IN/OUT: ptr to modeling info
738 RETURNS
739 Return SUCCEED or FAIL
740 DESCRIPTION
741 Parses the compression header from a data element in an HDF file.
742
743 GLOBAL VARIABLES
744 COMMENTS, BUGS, ASSUMPTIONS
745 EXAMPLES
746 REVISION LOG
747 --------------------------------------------------------------------------*/
748 PRIVATE int32
HCIread_header(accrec_t * access_rec,compinfo_t * info,comp_info * c_info,model_info * m_info)749 HCIread_header(accrec_t * access_rec,
750 compinfo_t * info, comp_info * c_info, model_info * m_info)
751 {
752 CONSTR(FUNC, "HCIread_header"); /* for HERROR */
753 uint16 header_version; /* version of the compression header */
754 uint8 *p; /* pointer to the temporary buffer */
755 uint8 *local_ptbuf;
756 int32 ret_value=SUCCEED;
757
758 /* shut compiler up */
759 m_info = m_info;
760
761 /* Get the compression header (description record) */
762 HPread_drec(access_rec->file_id, access_rec->ddid, &local_ptbuf);
763
764 /* Extract info */
765 p = local_ptbuf+2;
766 UINT16DECODE(p, header_version); /* get compression version */
767 INT32DECODE(p, info->length); /* get _uncompressed_ data length */
768 UINT16DECODE(p, info->comp_ref); /* get ref # of comp. data */
769
770 /* Decode the compression header */
771 if(HCPdecode_header(p,&(info->minfo.model_type),m_info,&(info->cinfo.coder_type),c_info)==FAIL)
772 HGOTO_ERROR(DFE_INTERNAL, FAIL);
773 HDfree(local_ptbuf);
774
775 done:
776 if(ret_value == FAIL)
777 { /* Error condition cleanup */
778
779 } /* end if */
780
781 /* Normal function cleanup */
782 return ret_value;
783 } /* end HCIread_header() */
784
785 /*--------------------------------------------------------------------------
786 NAME
787 HCcreate -- Create a compressed data element
788 USAGE
789 int32 HCcreate(id,tag,ref,model_type,coder_type)
790 int32 id; IN: the file id to create the data in
791 uint16 tag,ref; IN: the tag/ref pair which is to be compressed
792 comp_model_t model_type; IN: the type of modeling to use
793 model_info *m_info; IN: Information needed for the modeling type chosen
794 comp_coder_t coder_type; IN: the type of encoding to use
795 coder_info *c_info; IN: Information needed for the encoding type chosen
796 RETURNS
797 Return an AID to the newly created compressed element, FAIL on error.
798 DESCRIPTION
799 Create a compressed data element. If that data element already
800 exists, we will compress that data element if it is currently un-compresed,
801 or return FAIL if it is already compressed.
802
803 GLOBAL VARIABLES
804 COMMENTS, BUGS, ASSUMPTIONS
805 EXAMPLES
806 REVISION LOG
807 --------------------------------------------------------------------------*/
808 int32
HCcreate(int32 file_id,uint16 tag,uint16 ref,comp_model_t model_type,model_info * m_info,comp_coder_t coder_type,comp_info * c_info)809 HCcreate(int32 file_id, uint16 tag, uint16 ref, comp_model_t model_type,
810 model_info * m_info, comp_coder_t coder_type,
811 comp_info * c_info)
812 {
813 CONSTR(FUNC, "HCcreate"); /* for HERROR */
814 filerec_t *file_rec; /* file record */
815 accrec_t *access_rec=NULL;/* access element record */
816 compinfo_t *info=NULL; /* special element information */
817 atom_t data_id=FAIL; /* dd ID of existing regular element */
818 int32 data_len; /* length of the data we are checking */
819 uint16 special_tag; /* special version of tag */
820 void * buf = NULL; /* temporary buffer */
821 int32 ret_value=SUCCEED;
822
823 /* clear error stack and validate args */
824 HEclear();
825 file_rec = HAatom_object(file_id);
826 if (BADFREC(file_rec) || SPECIALTAG(tag)
827 || (special_tag = MKSPECIALTAG(tag)) == DFTAG_NULL)
828 HRETURN_ERROR(DFE_ARGS, FAIL);
829
830 /* chech for access permission */
831 if (!(file_rec->access & DFACC_WRITE))
832 HRETURN_ERROR(DFE_DENIED, FAIL);
833
834 /* get a slot in the access records table */
835 if (NULL == (access_rec = HIget_access_rec()))
836 HRETURN_ERROR(DFE_TOOMANY, FAIL);
837
838 /* search for identical dd */
839 if ((data_id=HTPselect(file_rec,tag,ref))!=FAIL)
840 {
841 /* Check if the element is already special */
842 if (HTPis_special(data_id)==TRUE)
843 {
844 if (HTPendaccess(data_id) == FAIL)
845 HGOTO_ERROR(DFE_CANTFLUSH, FAIL);
846 HGOTO_ERROR(DFE_CANTMOD, FAIL);
847 } /* end if */
848
849 /* get the info for the dataset */
850 if(HTPinquire(data_id,NULL,NULL,NULL,&data_len)==FAIL)
851 {
852 if (HTPendaccess(data_id) == FAIL)
853 HGOTO_ERROR(DFE_CANTFLUSH, FAIL);
854 HGOTO_ERROR(DFE_INTERNAL, FAIL);
855 } /* end if */
856
857 if ((buf = HDmalloc((uint32) data_len)) == NULL)
858 HGOTO_ERROR(DFE_NOSPACE, FAIL);
859 if (Hgetelement(file_id, tag, ref, buf) == FAIL)
860 HGOTO_ERROR(DFE_READERROR, FAIL);
861 /* Delete the old DD from the file and memory hash table */
862 if (FAIL == HTPdelete(data_id))
863 HGOTO_ERROR(DFE_CANTDELDD, FAIL);
864
865 } /* end if */
866
867 /* set up the special element information and write it to file */
868 info = (compinfo_t *) HDmalloc(sizeof(compinfo_t));
869 access_rec->special_info = info;
870 if (info == NULL)
871 HGOTO_ERROR(DFE_NOSPACE, FAIL);
872
873 info->length = (data_id!=FAIL) ? data_len : COMP_START_BLOCK;
874
875 /* set up compressed special info structure */
876 info->attached = 1;
877 info->comp_ref = Htagnewref(file_id,DFTAG_COMPRESSED); /* get the new reference # */
878 if(HCIinit_model(DFACC_RDWR, &(info->minfo), model_type, m_info)==FAIL)
879 HGOTO_ERROR(DFE_MINIT,FAIL);
880 if(HCIinit_coder(DFACC_RDWR, &(info->cinfo), coder_type, c_info)==FAIL)
881 HGOTO_ERROR(DFE_CINIT,FAIL);
882
883 if (HCIwrite_header(file_id, info, special_tag, ref, c_info, m_info) == FAIL)
884 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
885
886 /* update access record and file record */
887 if((access_rec->ddid=HTPselect(file_rec,tag,ref))==FAIL)
888 HGOTO_ERROR(DFE_INTERNAL, FAIL);
889 access_rec->special_func = &comp_funcs;
890 access_rec->special = SPECIAL_COMP;
891 access_rec->posn = 0;
892 access_rec->access = DFACC_RDWR;
893 access_rec->file_id = file_id;
894 access_rec->appendable = FALSE; /* start data as non-appendable */
895 file_rec->attach++;
896
897 /* propagate the initialization down to the modeling layer */
898 if ((*(info->minfo.model_funcs.stwrite))(access_rec) == FAIL)
899 HGOTO_ERROR(DFE_MODEL, FAIL);
900
901 /* compress the old DD and get rid of it, if there was one */
902 if (data_id != FAIL)
903 {
904 /* write the data through to the compression layer */
905 if (HCPwrite(access_rec, data_len, buf) == FAIL)
906 HGOTO_ERROR(DFE_MODEL, FAIL);
907
908 /* seek back to the beginning of the data through to the compression layer */
909 if (HCPseek(access_rec, 0, DF_START) == FAIL)
910 HGOTO_ERROR(DFE_MODEL, FAIL);
911 } /* end if */
912
913 ret_value=HAregister_atom(AIDGROUP,access_rec);
914
915 done:
916 if(ret_value == FAIL)
917 { /* Error condition cleanup */
918 if(access_rec!=NULL)
919 HIrelease_accrec_node(access_rec);
920 if(info!=NULL)
921 HDfree(info);
922 } /* end if */
923
924 /* Normal function cleanup */
925 if (buf != NULL)
926 HDfree(buf);
927
928 return ret_value;
929 } /* end HCcreate() */
930
931 /*--------------------------------------------------------------------------
932 NAME
933 HCPgetcompress -- Retrieves compression information of an element
934 USAGE
935 intn HCPgetcompress(aid, coder_type, c_info)
936 int32 aid; IN: access record ID
937 comp_coder_t* coder_type; OUT: the type of compression
938 comp_info* c_info; OUT: ptr to compression information
939 structure for storing the retrieved info
940 RETURNS
941 SUCCEED/FAIL
942 DESCRIPTION
943 This routine retrieves the compression type and the compression
944 information of the element, identified by 'aid'. The routine is
945 used by GRgetcompinfo and SDgetcompinfo at this time.
946
947 GLOBAL VARIABLES
948 COMMENTS, BUGS, ASSUMPTIONS
949 EXAMPLES
950 REVISION LOG
951 July 2001: Added to fix bug #307 - BMR
952 Dec. 2004: Changed name to HCPgetcompress, to be consistent with other
953 practice. REM
954 --------------------------------------------------------------------------*/
955 intn
HCPgetcompress(int32 file_id,uint16 data_tag,uint16 data_ref,comp_coder_t * comp_type,comp_info * c_info)956 HCPgetcompress(int32 file_id,
957 uint16 data_tag, uint16 data_ref,
958 comp_coder_t* comp_type, /* OUT: compression type */
959 comp_info* c_info) /* OUT: retrieved compression info */
960 {
961 CONSTR(FUNC, "HCPgetcompress"); /* for HGOTO_ERROR */
962 int32 aid=0, status;
963 accrec_t* access_rec=NULL;/* access element record */
964 compinfo_t* info=NULL; /* compressed element information */
965 model_info m_info; /* modeling information - dummy */
966 int32 ret_value=SUCCEED;
967
968 /* clear error stack */
969 HEclear();
970
971 /* start read access on the access record of the data element, which
972 is being inquired for its compression information */
973 aid = Hstartread(file_id, data_tag, data_ref);
974
975 /* get the access_rec pointer */
976 access_rec = HAatom_object(aid);
977 if (access_rec == NULL) HGOTO_ERROR(DFE_ARGS, FAIL);
978
979 /* if the element is compressed, get the compression info as requested*/
980 if (access_rec->special == SPECIAL_COMP)
981 {
982 info = (compinfo_t *) access_rec->special_info;
983 if (info == NULL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
984
985 status = HCIread_header(access_rec, info, c_info, &m_info);
986 if (status == FAIL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
987
988 /* get the compression type */
989 *comp_type = info->cinfo.coder_type;
990
991 } /* end if element is compressed */
992
993 /* if the element is chunked, call HMCgetcompress to get the
994 compression info as appropriate */
995 else if (access_rec->special == SPECIAL_CHUNKED)
996 {
997 status = HMCgetcompress(access_rec, comp_type, c_info);
998 if (status == FAIL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
999 }
1000
1001 /* flag the error when attempting to get compression info on a
1002 non-compressed element */
1003 else
1004 /* EIP 9/16/03 Fail but return compression type COMP_CODE_NONE
1005 instead of junk in this case.
1006 */
1007 {
1008 /*Mac OSX screams here (comp_coder_t)*comp_type = COMP_CODE_NONE; */
1009 *comp_type = COMP_CODE_NONE;
1010 HGOTO_ERROR(DFE_ARGS, FAIL);
1011 }
1012 /* end access to the aid appropriately */
1013 if (Hendaccess(aid)== FAIL)
1014 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1015
1016 done:
1017 if(ret_value == FAIL)
1018 { /* Error condition cleanup */
1019 /* end access to the aid if it's been accessed */
1020 if (aid != 0)
1021 if (Hendaccess(aid)== FAIL)
1022 HERROR(DFE_CANTENDACCESS);
1023 } /* end if */
1024
1025 /* Normal function cleanup */
1026 return ret_value;
1027 } /* HCPgetcompress */
1028
1029
1030 /*--------------------------------------------------------------------------
1031 NAME
1032 HCPgetcompinfo -- Retrieves compression information of an element
1033 USAGE
1034 intn HCPgetcompinfo(aid, coder_type, c_info)
1035 int32 aid; IN: access record ID
1036 comp_coder_t* coder_type; OUT: the type of compression
1037 comp_info* c_info; OUT: ptr to compression information
1038 structure for storing the retrieved info
1039 RETURNS
1040 SUCCEED/FAIL
1041 DESCRIPTION
1042 This routine retrieves the compression type and the compression
1043 information of the element, identified by 'aid'. The routine is
1044 used by GRgetcompinfo and SDgetcompinfo at this time.
1045
1046 GLOBAL VARIABLES
1047 COMMENTS, BUGS, ASSUMPTIONS
1048 EXAMPLES
1049 REVISION LOG
1050 July 2001: Added to fix bug #307 - BMR
1051 Dec. 2004: Changed name to HCPgetcompress, to be consistent with other
1052 practice. REM
1053 Apr. 2005: HCPgetcompinfo was added to fix bugzilla #130 and may replace
1054 HCPgetcompress in the future because HCPgetcompress did not
1055 behave correctly. The revision logs above are carried over
1056 from HCPgetcompress for the records.
1057 --------------------------------------------------------------------------*/
1058 intn
HCPgetcompinfo(int32 file_id,uint16 data_tag,uint16 data_ref,comp_coder_t * comp_type,comp_info * c_info)1059 HCPgetcompinfo(int32 file_id,
1060 uint16 data_tag, uint16 data_ref,
1061 comp_coder_t* comp_type, /* OUT: compression type */
1062 comp_info* c_info) /* OUT: retrieved compression info */
1063 {
1064 CONSTR(FUNC, "HCPgetcompinfo"); /* for HGOTO_ERROR */
1065 int32 aid=0, status;
1066 accrec_t* access_rec=NULL; /* access element record */
1067 compinfo_t* info=NULL; /* compressed element information */
1068 comp_coder_t temp_coder=COMP_CODE_NONE;
1069 model_info m_info; /* modeling information - dummy */
1070 intn ret_value=SUCCEED;
1071
1072 /* clear error stack */
1073 HEclear();
1074
1075 /* check the output arguments */
1076 if (comp_type == NULL || c_info == NULL)
1077 HGOTO_ERROR(DFE_ARGS, FAIL);
1078
1079 /* start read access on the access record of the data element, which
1080 is being inquired for its compression information */
1081 aid = Hstartread(file_id, data_tag, data_ref);
1082
1083 /* get the access_rec pointer */
1084 access_rec = HAatom_object(aid);
1085 if (access_rec == NULL) HGOTO_ERROR(DFE_ARGS, FAIL);
1086
1087 /* if the element is compressed, get the compression info as requested */
1088 if (access_rec->special == SPECIAL_COMP)
1089 {
1090 info = (compinfo_t *) access_rec->special_info;
1091 if (info == NULL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
1092
1093 status = HCIread_header(access_rec, info, c_info, &m_info);
1094 if (status == FAIL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
1095
1096 /* get the compression type */
1097 temp_coder = info->cinfo.coder_type;
1098
1099 } /* end if element is compressed */
1100
1101 /* if the element is chunked, call HMCgetcompress to get the
1102 compression info as appropriate */
1103 else if (access_rec->special == SPECIAL_CHUNKED)
1104 {
1105 status = HMCgetcompress(access_rec, &temp_coder, c_info);
1106 if (status == FAIL) HGOTO_ERROR(DFE_COMPINFO, FAIL);
1107 }
1108
1109 /* return COMP_CODE_NONE for a non-compressed element */
1110 /* Note: SPECIAL_COMPRAS may need special handling */
1111 else if (access_rec->special == SPECIAL_LINKED ||
1112 access_rec->special == SPECIAL_EXT ||
1113 access_rec->special == SPECIAL_VLINKED ||
1114 access_rec->special == SPECIAL_BUFFERED ||
1115 access_rec->special == SPECIAL_COMPRAS ||
1116 access_rec->special == 0)
1117 {
1118 temp_coder = COMP_CODE_NONE;
1119 }
1120
1121 /* flag the error when access_rec->special is not something valid */
1122 else
1123 {
1124 temp_coder = COMP_CODE_INVALID;
1125 HGOTO_ERROR(DFE_ARGS, FAIL);
1126 }
1127 /* end access to the aid appropriately */
1128 if (Hendaccess(aid)== FAIL)
1129 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1130
1131 if (comp_type != NULL) *comp_type = temp_coder;
1132
1133 done:
1134 if(ret_value == FAIL)
1135 { /* Error condition cleanup */
1136 /* end access to the aid if it's been accessed */
1137 if (aid != 0)
1138 if (Hendaccess(aid)== FAIL)
1139 HERROR(DFE_CANTENDACCESS);
1140 } /* end if */
1141
1142 /* Normal function cleanup */
1143 return ret_value;
1144 } /* HCPgetcompinfo */
1145
1146 /*--------------------------------------------------------------------------
1147 NAME
1148 HCIstaccess -- Start accessing a compressed data element.
1149 USAGE
1150 int32 HCIstaccess(access_rec, access)
1151 accrec_t *access_rec; IN: the access record of the data element
1152 int16 access; IN: the type of access wanted
1153 RETURNS
1154 Returns an AID or FAIL
1155 DESCRIPTION
1156 Common code called by HCIstread and HCIstwrite
1157
1158 GLOBAL VARIABLES
1159 COMMENTS, BUGS, ASSUMPTIONS
1160 EXAMPLES
1161 REVISION LOG
1162 --------------------------------------------------------------------------*/
1163 PRIVATE int32
HCIstaccess(accrec_t * access_rec,int16 acc_mode)1164 HCIstaccess(accrec_t * access_rec, int16 acc_mode)
1165 {
1166 CONSTR(FUNC, "HCIstaccess"); /* for HERROR */
1167 compinfo_t *info=NULL; /* special element information */
1168 filerec_t *file_rec; /* file record */
1169 comp_info c_info; /* encoding information from the header */
1170 model_info m_info; /* modeling information from the header */
1171 int32 ret_value=SUCCEED;
1172
1173 /* get file record and validate */
1174 file_rec = HAatom_object(access_rec->file_id);
1175 if (BADFREC(file_rec) || !(file_rec->access & acc_mode))
1176 HRETURN_ERROR(DFE_ARGS, FAIL);
1177
1178 /* intialize the access record */
1179 access_rec->special = SPECIAL_COMP;
1180 access_rec->posn = 0;
1181 access_rec->access = (uint32)(acc_mode|DFACC_READ);
1182
1183 /* get the special info record */
1184 access_rec->special_info = HDmalloc(sizeof(compinfo_t));
1185 info = (compinfo_t *) access_rec->special_info;
1186 if (info == NULL)
1187 HGOTO_ERROR(DFE_NOSPACE, FAIL);
1188
1189 if (HCIread_header(access_rec, info, &c_info, &m_info) == FAIL)
1190 HGOTO_ERROR(DFE_COMPINFO, FAIL);
1191 info->attached = 1;
1192 if (HCIinit_model(acc_mode,&(info->minfo), info->minfo.model_type, &m_info) == FAIL)
1193 HRETURN_ERROR(DFE_MINIT, FAIL);
1194 if (HCIinit_coder(acc_mode,&(info->cinfo), info->cinfo.coder_type, &c_info) == FAIL)
1195 HRETURN_ERROR(DFE_CINIT, FAIL);
1196
1197 file_rec->attach++;
1198
1199 ret_value=HAregister_atom(AIDGROUP,access_rec);
1200
1201 done:
1202 if(ret_value == FAIL)
1203 { /* Error condition cleanup */
1204 if(info!=NULL)
1205 HDfree(info);
1206 } /* end if */
1207
1208 /* Normal function cleanup */
1209 return ret_value;
1210 } /* end HCIstaccess() */
1211
1212 /*--------------------------------------------------------------------------
1213 NAME
1214 HCPstread -- Start read access on a compressed data element.
1215 USAGE
1216 int32 HCPstread(access_rec)
1217 accrec_t *access_rec; IN: the access record of the data element
1218 RETURNS
1219 Returns an AID or FAIL
1220 DESCRIPTION
1221 Start read access on a compressed data element.
1222
1223 GLOBAL VARIABLES
1224 COMMENTS, BUGS, ASSUMPTIONS
1225 EXAMPLES
1226 REVISION LOG
1227 --------------------------------------------------------------------------*/
1228 int32
HCPstread(accrec_t * access_rec)1229 HCPstread(accrec_t * access_rec)
1230 {
1231 CONSTR(FUNC, "HCPstread"); /* for HERROR */
1232 compinfo_t *info; /* information on the special element */
1233 int32 ret_value; /* AID to return */
1234
1235 if ((ret_value = HCIstaccess(access_rec, DFACC_READ)) == FAIL)
1236 HGOTO_ERROR(DFE_DENIED, FAIL);
1237 info = (compinfo_t *) access_rec->special_info;
1238 if ((*(info->minfo.model_funcs.stread)) (access_rec) == FAIL)
1239 HGOTO_ERROR(DFE_MODEL, FAIL);
1240
1241 done:
1242 if(ret_value == FAIL)
1243 { /* Error condition cleanup */
1244
1245 } /* end if */
1246
1247 /* Normal function cleanup */
1248 return ret_value;
1249 } /* end HCPstread() */
1250
1251 /*--------------------------------------------------------------------------
1252 NAME
1253 HCPstwrite -- Start write access on a compressed data element.
1254 USAGE
1255 int32 HCPstwrite(access_rec)
1256 accrec_t *access_rec; IN: the access record of the data element
1257 RETURNS
1258 Returns an AID or FAIL
1259 DESCRIPTION
1260 Start write access on a compressed data element.
1261
1262 GLOBAL VARIABLES
1263 COMMENTS, BUGS, ASSUMPTIONS
1264 EXAMPLES
1265 REVISION LOG
1266 --------------------------------------------------------------------------*/
1267 int32
HCPstwrite(accrec_t * access_rec)1268 HCPstwrite(accrec_t * access_rec)
1269 {
1270 CONSTR(FUNC, "HCPstwrite"); /* for HERROR */
1271 compinfo_t *info; /* information on the special element */
1272 int32 ret_value; /* AID to return */
1273
1274 if ((ret_value = HCIstaccess(access_rec, DFACC_WRITE)) == FAIL)
1275 HGOTO_ERROR(DFE_DENIED, FAIL);
1276 info = (compinfo_t *) access_rec->special_info;
1277 if ((*(info->minfo.model_funcs.stwrite)) (access_rec) == FAIL)
1278 HGOTO_ERROR(DFE_MODEL, FAIL);
1279
1280 done:
1281 if(ret_value == FAIL)
1282 { /* Error condition cleanup */
1283
1284 } /* end if */
1285
1286 /* Normal function cleanup */
1287 return ret_value;
1288 } /* end HCPstwrite() */
1289
1290 /*--------------------------------------------------------------------------
1291 NAME
1292 HCPseek -- Seek to offset within the data element
1293 USAGE
1294 int32 HCPseek(access_rec,offset,origin)
1295 accrec_t *access_rec; IN: the access record of the data element
1296 int32 offset; IN: the offset in bytes from the origin specified
1297 intn origin; IN: the origin to seek from
1298 RETURNS
1299 Returns SUCCEED or FAIL
1300 DESCRIPTION
1301 Seek to a position with a compressed data element.
1302
1303 GLOBAL VARIABLES
1304 COMMENTS, BUGS, ASSUMPTIONS
1305 EXAMPLES
1306 REVISION LOG
1307 --------------------------------------------------------------------------*/
1308 int32
HCPseek(accrec_t * access_rec,int32 offset,intn origin)1309 HCPseek(accrec_t * access_rec, int32 offset, intn origin)
1310 {
1311 CONSTR(FUNC, "HCPseek"); /* for HERROR */
1312 compinfo_t *info; /* information on the special element */
1313 int32 ret_value;
1314
1315 /* Adjust offset according to origin. There is no upper bound to posn */
1316 if (origin == DF_CURRENT)
1317 offset += access_rec->posn;
1318 if (origin == DF_END)
1319 offset += ((compinfo_t *) (access_rec->special_info))->length;
1320 if (offset < 0)
1321 HGOTO_ERROR(DFE_RANGE, FAIL);
1322
1323 info = (compinfo_t *) access_rec->special_info;
1324 if ((ret_value = (*(info->minfo.model_funcs.seek)) (access_rec, offset, origin)) == FAIL)
1325 HGOTO_ERROR(DFE_MODEL, FAIL);
1326
1327 /* set the offset */
1328 access_rec->posn = offset;
1329
1330 done:
1331 if(ret_value == FAIL)
1332 { /* Error condition cleanup */
1333
1334 } /* end if */
1335
1336 /* Normal function cleanup */
1337 return ret_value;
1338 } /* end HCPseek() */
1339
1340 /*--------------------------------------------------------------------------
1341 NAME
1342 HCPread -- Read in a portion of data from a compressed data element.
1343 USAGE
1344 int32 HCPread(access_rec,length,data)
1345 accrec_t *access_rec; IN: the access record of the data element
1346 int32 length; IN: the number of bytes to read
1347 void * data; OUT: the buffer to place the bytes read
1348 RETURNS
1349 Returns the number of bytes read or FAIL
1350 DESCRIPTION
1351 Read in a number of bytes from a compressed data element.
1352
1353 GLOBAL VARIABLES
1354 COMMENTS, BUGS, ASSUMPTIONS
1355 EXAMPLES
1356 REVISION LOG
1357 --------------------------------------------------------------------------*/
1358 int32
HCPread(accrec_t * access_rec,int32 length,void * data)1359 HCPread(accrec_t * access_rec, int32 length, void * data)
1360 {
1361 CONSTR(FUNC, "HCPread"); /* for HERROR */
1362 compinfo_t *info; /* information on the special element */
1363 int32 ret_value;
1364
1365 /* validate length */
1366 if (length < 0)
1367 HGOTO_ERROR(DFE_RANGE, FAIL);
1368
1369 info = (compinfo_t *) access_rec->special_info;
1370
1371 /* adjust length if it falls off the end of the element */
1372 if (length == 0)
1373 length = info->length - access_rec->posn;
1374 else if (length < 0 || access_rec->posn + length > info->length)
1375 HGOTO_ERROR(DFE_RANGE, FAIL);
1376
1377 if ((*(info->minfo.model_funcs.read))(access_rec, length, data) == FAIL)
1378 HGOTO_ERROR(DFE_MODEL, FAIL);
1379
1380 /* adjust access position */
1381 access_rec->posn += length;
1382
1383 ret_value=length;
1384
1385 done:
1386 if(ret_value == FAIL)
1387 { /* Error condition cleanup */
1388
1389 } /* end if */
1390
1391 /* Normal function cleanup */
1392 return ret_value;
1393 } /* end HCPread() */
1394
1395 /*--------------------------------------------------------------------------
1396 NAME
1397 HCPwrite -- Write out a portion of data from a compressed data element.
1398 USAGE
1399 int32 HCPwrite(access_rec,length,data)
1400 accrec_t *access_rec; IN: the access record of the data element
1401 int32 length; IN: the number of bytes to write
1402 void * data; IN: the buffer to retrieve the bytes written
1403 RETURNS
1404 Returns the number of bytes written or FAIL
1405 DESCRIPTION
1406 Write out a number of bytes to a compressed data element.
1407
1408 GLOBAL VARIABLES
1409 COMMENTS, BUGS, ASSUMPTIONS
1410 EXAMPLES
1411 REVISION LOG
1412 --------------------------------------------------------------------------*/
1413 int32
HCPwrite(accrec_t * access_rec,int32 length,const void * data)1414 HCPwrite(accrec_t * access_rec, int32 length, const void * data)
1415 {
1416 CONSTR(FUNC, "HCPwrite"); /* for HERROR */
1417 compinfo_t *info; /* information on the special element */
1418 uint8 local_ptbuf[4];
1419 uint8 *p = local_ptbuf; /* temp buffer ptr */
1420 filerec_t *file_rec; /* file record */
1421 int32 ret_value;
1422
1423 /* convert file id to file record */
1424 file_rec = HAatom_object(access_rec->file_id);
1425
1426 /* validate length */
1427 if (length < 0)
1428 HRETURN_ERROR(DFE_RANGE, FAIL);
1429
1430 info = (compinfo_t *) access_rec->special_info;
1431 if ((*(info->minfo.model_funcs.write)) (access_rec, length, data) == FAIL)
1432 HGOTO_ERROR(DFE_MODEL, FAIL);
1433
1434 /* update access record, and information about special element */
1435 access_rec->posn += length;
1436 if (access_rec->posn > info->length)
1437 {
1438 int32 data_off; /* offset of the data we are checking */
1439
1440 /* get the info for the dataset */
1441 if(HTPinquire(access_rec->ddid,NULL,NULL,&data_off,NULL)==FAIL)
1442 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1443
1444 info->length = access_rec->posn;
1445
1446 INT32ENCODE(p, info->length);
1447 if (HPseek(file_rec, data_off + 4) == FAIL)
1448 HGOTO_ERROR(DFE_SEEKERROR, FAIL);
1449 /* re-write un-comp. len */
1450 if (HP_write(file_rec, local_ptbuf, 4) == FAIL)
1451 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
1452 } /* end if */
1453
1454 ret_value=length; /* return length of bytes written */
1455
1456 done:
1457 if(ret_value == FAIL)
1458 { /* Error condition cleanup */
1459
1460 } /* end if */
1461
1462 /* Normal function cleanup */
1463 return ret_value;
1464 } /* end HCPwrite() */
1465
1466 /*--------------------------------------------------------------------------
1467 NAME
1468 HCPinquire -- Inquire information about the access record and data element.
1469 USAGE
1470 int32 HCPinquire(access_rec,pfile_id,ptag,pref,plength,poffset,pposn,
1471 paccess,pspecial)
1472 accrec_t *access_rec; IN: the access record of the data element
1473 int32 *pfile_id; OUT: ptr to file id
1474 uint16 *ptag; OUT: ptr to tag of information
1475 uint16 *pref; OUT: ptr to ref of information
1476 int32 *plength; OUT: ptr to length of data element
1477 int32 *poffset; OUT: ptr to offset of data element
1478 int32 *pposn; OUT: ptr to position of access in element
1479 int16 *paccess; OUT: ptr to access mode
1480 int16 *pspecial; OUT: ptr to special code
1481 RETURNS
1482 Returns SUCCEED or FAIL
1483 DESCRIPTION
1484 Inquire information about the access record and data element.
1485
1486 GLOBAL VARIABLES
1487 COMMENTS, BUGS, ASSUMPTIONS
1488 EXAMPLES
1489 REVISION LOG
1490 --------------------------------------------------------------------------*/
1491 int32
HCPinquire(accrec_t * access_rec,int32 * pfile_id,uint16 * ptag,uint16 * pref,int32 * plength,int32 * poffset,int32 * pposn,int16 * paccess,int16 * pspecial)1492 HCPinquire(accrec_t * access_rec, int32 *pfile_id, uint16 *ptag,
1493 uint16 *pref, int32 *plength, int32 *poffset, int32 *pposn, int16 *paccess,
1494 int16 *pspecial)
1495 {
1496 CONSTR(FUNC, "HCPinquire"); /* for HERROR */
1497 compinfo_t *info = /* special information record */
1498 (compinfo_t *) access_rec->special_info;
1499 uint16 data_tag,data_ref; /* tag/ref of the data we are checking */
1500 int32 data_off; /* offset of the data we are checking */
1501
1502 /* get the info for the dataset */
1503 if(HTPinquire(access_rec->ddid,&data_tag,&data_ref,&data_off,NULL)==FAIL)
1504 HRETURN_ERROR(DFE_INTERNAL, FAIL);
1505
1506 /* fill in the variables if they are present */
1507 if (pfile_id != NULL)
1508 *pfile_id = access_rec->file_id;
1509 if (ptag != NULL)
1510 *ptag = data_tag;
1511 if (pref != NULL)
1512 *pref = data_ref;
1513 if (plength != NULL)
1514 *plength = info->length;
1515 if (poffset != NULL)
1516 *poffset = data_off;
1517 if (pposn != NULL)
1518 *pposn = access_rec->posn;
1519 if (paccess != NULL)
1520 *paccess = (int16)access_rec->access;
1521 if (pspecial != NULL)
1522 *pspecial = (int16)access_rec->special;
1523
1524 return (SUCCEED);
1525 } /* end HCPinquire() */
1526
1527 /*--------------------------------------------------------------------------
1528 NAME
1529 HCPendaccess -- Close the compressed data element and free the AID
1530 USAGE
1531 intn HCPendaccess(access_rec)
1532 accrec_t *access_rec; IN: the access record of the data element
1533 RETURNS
1534 Returns SUCCEED or FAIL
1535 DESCRIPTION
1536 Close the compressed data element and free the AID.
1537
1538 GLOBAL VARIABLES
1539 COMMENTS, BUGS, ASSUMPTIONS
1540 EXAMPLES
1541 REVISION LOG
1542 --------------------------------------------------------------------------*/
1543 intn
HCPendaccess(accrec_t * access_rec)1544 HCPendaccess(accrec_t * access_rec)
1545 {
1546 CONSTR(FUNC, "HCPendaccess"); /* for HERROR */
1547 filerec_t *file_rec; /* file record */
1548 intn ret_value = SUCCEED;
1549
1550 /* validate argument */
1551 if (access_rec == NULL)
1552 HGOTO_ERROR(DFE_ARGS, FAIL);
1553
1554 /* convert file id to file record */
1555 file_rec = HAatom_object(access_rec->file_id);
1556 if (BADFREC(file_rec))
1557 HGOTO_ERROR(DFE_ARGS, FAIL);
1558
1559 /* close the file pointed to by this access rec */
1560 if (HCPcloseAID(access_rec) == FAIL)
1561 HGOTO_ERROR(DFE_CANTCLOSE, FAIL);
1562
1563 /* update file and access records */
1564 if (HTPendaccess(access_rec->ddid) == FAIL)
1565 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1566
1567 /* detach from the file */
1568 file_rec->attach--;
1569
1570 /* free the access record */
1571 HIrelease_accrec_node(access_rec);
1572
1573 done:
1574 if(ret_value == FAIL)
1575 { /* Error condition cleanup */
1576 if(access_rec!=NULL)
1577 HIrelease_accrec_node(access_rec);
1578 } /* end if */
1579
1580 /* Normal function cleanup */
1581
1582 return ret_value;
1583 } /* end HCPendaccess() */
1584
1585 /*--------------------------------------------------------------------------
1586 NAME
1587 HCPcloseAID -- Get rid of the compressed data element data structures
1588 USAGE
1589 int32 HCPcloseAID(access_rec)
1590 accrec_t *access_rec; IN: the access record of the data element
1591 RETURNS
1592 Returns SUCCEED or FAIL
1593 DESCRIPTION
1594 Get rid of the compressed data element internal data structures
1595
1596 GLOBAL VARIABLES
1597 COMMENTS, BUGS, ASSUMPTIONS
1598 EXAMPLES
1599 REVISION LOG
1600 --------------------------------------------------------------------------*/
1601 int32
HCPcloseAID(accrec_t * access_rec)1602 HCPcloseAID(accrec_t * access_rec)
1603 {
1604 CONSTR(FUNC, "HCPcloseAID"); /* for HERROR */
1605 compinfo_t *info; /* special information record */
1606 int32 ret=SUCCEED;
1607
1608 info = (compinfo_t *) access_rec->special_info;
1609 if ((ret = (*(info->minfo.model_funcs.endaccess)) (access_rec)) == FAIL)
1610 HRETURN_ERROR(DFE_MODEL, FAIL);
1611
1612 /* Free the compression information */
1613 /* BMR - reset special_info to NULL after memory is freed; problem shown
1614 by the failure when running hdp list with a large file on PC - 12/6/98 */
1615 if (--(info->attached) == 0)
1616 {
1617 HDfree(info);
1618 access_rec->special_info = NULL;
1619 }
1620 return (ret);
1621 } /* end HCPcloseAID() */
1622
1623 /* ------------------------------- HCPinfo -------------------------------- */
1624 /*
1625 NAME
1626 HCPinfo -- return info about a compressed element
1627 USAGE
1628 int32 HCPinfo(access_rec, info_block)
1629 accrec_t * access_rec; IN: access record of access element
1630 sp_info_block_t * info_block; OUT: information about the special element
1631 RETURNS
1632 SUCCEED / FAIL
1633 DESCRIPTION
1634 Return information about the given compressed element. Info_block is
1635 assumed to be non-NULL.
1636
1637 ---------------------------------------------------------------------------*/
1638 int32
HCPinfo(accrec_t * access_rec,sp_info_block_t * info_block)1639 HCPinfo(accrec_t * access_rec, sp_info_block_t * info_block)
1640 {
1641 CONSTR(FUNC, "HCPinfo");
1642 compinfo_t *info = /* special information record */
1643 (compinfo_t *) access_rec->special_info;
1644
1645 /* validate access record */
1646 if (access_rec->special != SPECIAL_COMP)
1647 HRETURN_ERROR(DFE_INTERNAL, FAIL);
1648
1649 /* fill in the info_block */
1650 info_block->key = SPECIAL_COMP;
1651
1652 info_block->comp_type = (int32)info->cinfo.coder_type;
1653 info_block->model_type = (int32)info->minfo.model_type;
1654 info_block->comp_size = Hlength(access_rec->file_id, DFTAG_COMPRESSED, info->comp_ref);
1655
1656 return SUCCEED;
1657 } /* HCPinfo */
1658
1659 /* ------------------------------- HCPgetinfo ----------------------------- */
1660 /*
1661 NAME
1662 HCget_config_info -- return info about configuration of a compression method
1663
1664 USAGE
1665 intn HCget_config_info( comp_coder_t coder_type,
1666 uint32* compression_config_info)
1667 comp_coder_t coder_type; IN: the compression type queried
1668 compression_config_info; OUT: flags to indiat compression status
1669
1670 0 -- not enabled
1671 COMP_DECODER_ENABLED - decoding enabled
1672 COMP_ENCODER_ENABLED - encoding enabled
1673
1674 RETURNS
1675 SUCCEED / FAIL
1676 DESCRIPTION
1677 Return information about the given compresion method.
1678
1679 Currently, reports if encoding and/or decoding are available. SZIP
1680 is the only method that varies in the current versions.
1681
1682
1683 ---------------------------------------------------------------------------*/
1684 intn
HCget_config_info(comp_coder_t coder_type,uint32 * compression_config_info)1685 HCget_config_info( comp_coder_t coder_type, /* IN: compression type */
1686 uint32* compression_config_info)
1687 {
1688 CONSTR(FUNC, "HCget_config_info");
1689
1690 *compression_config_info = 0;
1691 switch (coder_type)
1692 {
1693 case COMP_CODE_IMCOMP: /* IMCOMP no longer supported */
1694 *compression_config_info = 0;
1695 break;
1696 /* This block doesn't look intentional, for there is no "break;"
1697 before case COMP_CODE_RLE:, which means *compression_config_info
1698 was reassigned to something else even though it is "case
1699 COMP_CODE_NONE:" When I added "break;" for "case COMP_CODE_NONE:", some tests failed. It needs to be checked out.-BMR, Jul 16, 2012*/
1700 case COMP_CODE_NONE: /* "none" (i.e. no) encoding */
1701 *compression_config_info = 0;
1702 case COMP_CODE_RLE: /* Run-length encoding */
1703 case COMP_CODE_NBIT: /* N-bit encoding */
1704 case COMP_CODE_SKPHUFF: /* Skipping Huffman encoding */
1705 *compression_config_info = COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED;
1706 break;
1707
1708 case COMP_CODE_JPEG: /* jpeg may be optional */
1709 *compression_config_info = COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED;
1710 break;
1711 case COMP_CODE_DEFLATE: /* gzip 'deflate' encoding, maybe optional */
1712 *compression_config_info = COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED;
1713 break;
1714
1715 case COMP_CODE_SZIP:
1716 #ifdef H4_HAVE_LIBSZ
1717 if (SZ_encoder_enabled()) {
1718 *compression_config_info = COMP_DECODER_ENABLED|COMP_ENCODER_ENABLED;
1719 } else {
1720 *compression_config_info = COMP_DECODER_ENABLED;
1721 }
1722 #else
1723 *compression_config_info = 0;
1724 #endif /* H4_HAVE_LIBSZ */
1725 break;
1726 default:
1727 *compression_config_info = 0;
1728 HRETURN_ERROR(DFE_BADCODER, FAIL)
1729 }
1730 return SUCCEED;
1731 }
1732
1733 /*--------------------------------------------------------------------------
1734 NAME
1735 HCPgetcomptype -- Retrieves compression type of an element
1736 USAGE
1737 intn HCPgetcomptype(aid, coder_type)
1738 int32 aid; IN: access record ID
1739 comp_coder_t* coder_type; OUT: the type of compression
1740 RETURNS
1741 SUCCEED/FAIL
1742 DESCRIPTION
1743 This routine retrieves the compression type of the element, identified
1744 by 'aid'. It is very similar to HCPgetcompinfo except that it only
1745 retrieves the compression type and not the compression information. The
1746 routine is used by GRgetcomptype and SDgetcomptype.
1747
1748 GLOBAL VARIABLES
1749 COMMENTS, BUGS, ASSUMPTIONS
1750 EXAMPLES
1751 REVISION LOG
1752 Dec. 2007: Added so that applications can get the compression method only.
1753 The immediate intention is to avoid the need for external
1754 libraries to be present when only compression type is desired
1755 and not compression information. -BMR
1756 --------------------------------------------------------------------------*/
1757 intn
HCPgetcomptype(int32 file_id,uint16 data_tag,uint16 data_ref,comp_coder_t * comp_type)1758 HCPgetcomptype(int32 file_id,
1759 uint16 data_tag, uint16 data_ref, /* IN: tag/ref of element */
1760 comp_coder_t* comp_type) /* OUT: compression type */
1761 {
1762 CONSTR(FUNC, "HCPgetcomptype"); /* for HGOTO_ERROR */
1763 uint16 ctag, cref; /* tag/ref for the special info header object */
1764 int32 data_id=FAIL; /* temporary AID for header info */
1765 int32 temp_aid=FAIL; /* temporary AID for header info */
1766 int32 data_len; /* offset of the data we are checking */
1767 uint8 *p; /* pointers to the temporary buffer */
1768 uint8 *local_ptbuf=NULL; /* temporary buffer */
1769 uint16 sp_tag; /* special tag */
1770 uint16 c_type; /* compression type */
1771 filerec_t *file_rec; /* file record */
1772 intn ret_value=SUCCEED;
1773
1774 /* clear error stack */
1775 HEclear();
1776
1777 /* convert file id to file rec and check for validity */
1778 file_rec = HAatom_object(file_id);
1779 if (BADFREC(file_rec))
1780 HGOTO_ERROR(DFE_ARGS, FAIL);
1781
1782 /* get access element from dataset's tag/ref */
1783 if ((data_id=HTPselect(file_rec, data_tag, data_ref))!=FAIL)
1784 {
1785 /* get the info for the dataset */
1786 if(HTPinquire(data_id,&ctag,&cref,NULL,&data_len)==FAIL)
1787 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1788
1789 /* if element is not special, return COMP_CODE_NONE */
1790 if (!SPECIALTAG(ctag))
1791 {
1792 *comp_type = COMP_CODE_NONE;
1793 HGOTO_DONE(SUCCEED);
1794 }
1795
1796 /* element is special, proceed with reading special info header */
1797 if((local_ptbuf=(uint8 *)HDmalloc(data_len))==NULL)
1798 HGOTO_ERROR(DFE_NOSPACE, FAIL);
1799
1800 /* Get the special info header */
1801 if ((temp_aid=Hstartaccess(file_id,MKSPECIALTAG(ctag),cref,DFACC_READ)) == FAIL)
1802 HGOTO_ERROR(DFE_BADAID, FAIL);
1803 if (Hread(temp_aid,2,local_ptbuf) == FAIL)
1804 HGOTO_ERROR(DFE_READERROR, FAIL);
1805
1806 /* Get special tag */
1807 p = local_ptbuf;
1808 UINT16DECODE(p, sp_tag);
1809
1810 /* If it is a compressed element, move forward until compression
1811 coder and get it */
1812 switch (sp_tag)
1813 {
1814 case SPECIAL_COMP:
1815 if (Hread(temp_aid,12,local_ptbuf) == FAIL)
1816 HGOTO_ERROR(DFE_READERROR, FAIL);
1817
1818 /* Skip comp version, length, ref#, and model type */
1819 p = local_ptbuf + 2 + 4 + 2 + 2;
1820 UINT16DECODE(p, c_type); /* get encoding type */
1821 *comp_type=(comp_coder_t)c_type;
1822 break;
1823
1824 /* If element is chunked, hand over to the chunk interface to check
1825 if it is compressed and get the type */
1826 case SPECIAL_CHUNKED:
1827 if (HMCgetcomptype(temp_aid, comp_type)==FAIL)
1828 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1829 break;
1830
1831 /* return COMP_CODE_NONE for a non-compressed element */
1832 /* Developer's Note: SPECIAL_COMPRAS may need special handling */
1833 case SPECIAL_LINKED:
1834 case SPECIAL_EXT:
1835 case SPECIAL_VLINKED:
1836 case SPECIAL_BUFFERED:
1837 case SPECIAL_COMPRAS:
1838 case 0:
1839 *comp_type = COMP_CODE_NONE;
1840 break;
1841
1842 /* flag the error when special tag is not something valid */
1843 default:
1844 *comp_type = COMP_CODE_INVALID;
1845 HGOTO_ERROR(DFE_ARGS, FAIL);
1846 }
1847 }
1848 else /* no special element */
1849 {
1850 *comp_type = COMP_CODE_NONE;
1851 }
1852
1853 done:
1854 if(ret_value == FAIL)
1855 { /* Error condition cleanup */
1856 } /* end if */
1857
1858 /* end access to the aid's if they've been accessed */
1859 if (temp_aid != FAIL)
1860 if (Hendaccess(temp_aid)== FAIL)
1861 HERROR(DFE_CANTENDACCESS);
1862 if (data_id != FAIL)
1863 if (HTPendaccess(data_id)== FAIL)
1864 HERROR(DFE_CANTENDACCESS);
1865
1866 /* release allocated memory */
1867 if (local_ptbuf != NULL)
1868 HDfree(local_ptbuf);
1869
1870 /* Normal function cleanup */
1871 return ret_value;
1872 } /* HCPgetcomptype */
1873
1874
1875 /*--------------------------------------------------------------------------
1876 NAME
1877 HCPgetdatasize -- Retrieves the sizes of original and compressed data.
1878 USAGE
1879 int32 HCPgetdatasize(file_id, data_tag, data_ref, comp_size, orig_size)
1880 int32 file_id; IN: file id
1881 uint16 data_tag; IN: tag of the element
1882 uint16 data_ref; IN: ref of element
1883 int32* comp_size; OUT: size of compressed data
1884 int32* orig_size; OUT: size of non-compressed data
1885 RETURNS
1886 SUCCEED/FAIL
1887 DESCRIPTION
1888 This routine gets access to the element pointed to by the dataset's
1889 tag/ref pair, then proceeds as followed:
1890 - If the element is not special, HCPgetdatasize will use Hlength to get
1891 the length of the data then return.
1892 - If the element is compressed, HCPgetdatasize will read the element's
1893 special header and decode it for the uncompressed data length and the
1894 compressed data ref#, then use Hlength to get the length of the
1895 compressed data.
1896 - If the element is chunked, HCPgetdatasize will let the chunking layer
1897 retrieve the sizes (HMCgetdatasize.)
1898 GLOBAL VARIABLES
1899 COMMENTS, BUGS, ASSUMPTIONS
1900 EXAMPLES
1901 REVISION LOG
1902 --------------------------------------------------------------------------*/
1903 intn
HCPgetdatasize(int32 file_id,uint16 data_tag,uint16 data_ref,int32 * comp_size,int32 * orig_size)1904 HCPgetdatasize(int32 file_id,
1905 uint16 data_tag, uint16 data_ref, /* IN: tag/ref of element */
1906 int32* comp_size, /* OUT - size of compressed data */
1907 int32* orig_size) /* OUT - size of non-compressed data */
1908 {
1909 CONSTR(FUNC, "HCPgetdatasize"); /* for HGOTO_ERROR */
1910 uint8 *local_ptbuf=NULL, *p;
1911 uint16 sp_tag; /* special tag */
1912 uint16 comp_ref = 0;
1913 atom_t data_id = FAIL; /* dd ID of existing regular element */
1914 int32 len = 0;
1915 filerec_t *file_rec; /* file record */
1916 intn ret_value=SUCCEED;
1917
1918 /* clear error stack */
1919 HEclear();
1920
1921 /* convert file id to file rec and check for validity */
1922 file_rec = HAatom_object(file_id);
1923 if (BADFREC(file_rec))
1924 HGOTO_ERROR(DFE_ARGS, FAIL);
1925
1926 /* get access element from dataset's tag/ref */
1927 if ((data_id=HTPselect(file_rec, data_tag, data_ref))!=FAIL)
1928 {
1929 /* if the element is not special, that means dataset's tag/ref
1930 specifies the actual data that was written to the dataset, so
1931 we don't need to check further */
1932 if (HTPis_special(data_id)==FALSE)
1933 {
1934 if ((len = Hlength(file_id, data_tag, data_ref)) == FAIL)
1935 HGOTO_ERROR(DFE_BADLEN, FAIL);
1936 *orig_size = *comp_size = len;
1937 }
1938
1939 /* if the element is special, get the special info header and decode
1940 for the uncompressed data length and the compressed data ref#, which
1941 will be used with DFTAG_COMPRESSED to get the compressed data len */
1942 else
1943 {
1944 int32 rec_len=0;
1945
1946 /* Get the compression header (description record) */
1947 rec_len = HPread_drec(file_id, data_id, &local_ptbuf);
1948 if (rec_len <= 0)
1949 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1950
1951 /* get special tag */
1952 p = local_ptbuf;
1953 INT16DECODE(p, sp_tag);
1954
1955 /* verify that it is a compressed element, then get the data len */
1956 if (sp_tag == SPECIAL_COMP)
1957 {
1958 /* skip 2byte header_version */
1959 p = p + 2;
1960 INT32DECODE(p, len); /* get _uncompressed_ data length */
1961 *orig_size = len; /* set original data size */
1962
1963 /* if no data written, set compressed data size too */
1964 if (len == 0)
1965 {
1966 *comp_size = len;
1967 }
1968 /* Data has been written, get compressed data size */
1969 else
1970 {
1971 /* get ref# of compressed data */
1972 UINT16DECODE(p, comp_ref);
1973 if ((len = Hlength(file_id, DFTAG_COMPRESSED, comp_ref)) == FAIL)
1974 HGOTO_ERROR(DFE_BADLEN, FAIL);
1975 *comp_size = len; /* set compressed data size */
1976 } /* data written */
1977 } /* element is compressed */
1978
1979 /* if it is a chunked element, hand the task over to the chunking
1980 layer. */
1981 else if (sp_tag == SPECIAL_CHUNKED)
1982 {
1983 if (HMCgetdatasize(file_id, p, comp_size, orig_size)==FAIL)
1984 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1985 }
1986
1987 /* unlimited dimension and external data fall in here */
1988 else if (sp_tag == SPECIAL_LINKED || sp_tag == SPECIAL_EXT)
1989 {
1990 INT32DECODE(p, len); /* get total data length */
1991 *orig_size = *comp_size = len; /* set data sizes */
1992 }
1993 } /* else, data_id is special */
1994
1995 /* end access to the aid */
1996 if (HTPendaccess(data_id) == FAIL)
1997 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1998 } /* end if data_id != FAIL */
1999
2000 else /* HTPselect failed */
2001 HGOTO_ERROR(DFE_CANTACCESS, FAIL);
2002
2003 done:
2004 if(ret_value == FAIL)
2005 { /* Error condition cleanup */
2006 } /* end if */
2007
2008 /* Normal function cleanup */
2009 if (local_ptbuf != NULL)
2010 HDfree(local_ptbuf);
2011
2012 return ret_value;
2013 } /* HCPgetdatasize */
2014