📄 shpack_io.c
字号:
} else { end = num_elements; } num = end-start; for(i=0;i<num;i++) bits_for_element_cache[i] = -1; bits_for_chunk = 0; for(i=start;i<end;i++) { ind = i-start; if(bits_for_element_cache[ind] < 0) { abs_element = buffer[i & mask]; if(abs_element < 0) abs_element *= -1; bits_for_element_cache[ind] = find_bits_needed(abs_element); } bits_for_element = bits_for_element_cache[ind];/* printf("i %d mask %d abs %d\n", i, mask, abs_element);*/ if(bits_for_element > bits_for_chunk) { if( (i!= start) && better_to_chop_here_vs_using_more_bits(bits_for_element, bits_for_chunk, (i-start))) { *pbits = bits_for_chunk;/* printf("chopping upscale bits %d inchunk %d i %d\n", bits_for_element, bits_for_chunk, i);*/ return (i-start); } else { bits_for_chunk = bits_for_element; } } else if(bits_for_element < bits_for_chunk) { if(better_to_chop_here_and_use_fewer_bits_for_future(bits_for_element, bits_for_chunk, buffer, bits_for_element_cache, start, i, end, mask)) { *pbits = bits_for_chunk;/* printf("chopping downscale bits %d inchunk %d i %d\n", bits_for_element, bits_for_chunk, i);*/ return (i-start); } } }/* printf("no chopping inchunk %d i %d\n", bits_for_chunk, i);*/ *pbits = bits_for_chunk; return (i-start);}/*this figures out how many shorts will be needed to represent output if we chop now vs how many will be needed if we increase the bits for the chunk from bits_for_chunk to bits_for_element*/better_to_chop_here_vs_using_more_bits(bits_for_element, bits_for_chunk, num_in_chunk)int bits_for_element, bits_for_chunk, num_in_chunk;{ int els_so_far; int new_els; /* if we were to stop here and section off now.. */ els_so_far = ((bits_for_chunk * num_in_chunk) % 16 == 0) ? bits_for_chunk * num_in_chunk / 16 : bits_for_chunk * num_in_chunk / 16 + 1; els_so_far++; /*add one for the header*/ /* or to upgrade and continue? */ new_els = ((bits_for_element * num_in_chunk) % 16 == 0) ? bits_for_element * num_in_chunk / 16 : bits_for_element * num_in_chunk / 16 + 1; if (els_so_far < new_els) { return 1; } else { return (0); }}/*chop if number of bits saved for future is more than the header size. Check though to see if it will want to use less bits for for before these bits are saved (for steadily decreasing amp for example)*/better_to_chop_here_and_use_fewer_bits_for_future(bits_for_element, bits_for_chunk, buffer, bits_for_element_cache, cache_start, start, end, mask)short *buffer;int bits_for_element, bits_for_chunk;short *bits_for_element_cache;int start, end, mask;{ int bits_saved_per_element; register int i, j, k; int bits; short abs_element; int max_bits; int real_end; int ind; max_bits = bits_for_element; if(end > start+16) { real_end = start+16; } else { real_end = end; } for(i=start+1;i<real_end;i++) { ind = i-cache_start; if(bits_for_element_cache[ind] < 0) { abs_element = buffer[i & mask]; if(abs_element < 0) abs_element *= -1; bits_for_element_cache[ind] = find_bits_needed(abs_element); } bits = bits_for_element_cache[ind]; if(bits > max_bits) { max_bits = bits; } bits_saved_per_element = (bits_for_chunk - max_bits); if(bits_saved_per_element <= 0) break; /*no hope for saving any bits*/ if((bits_saved_per_element * (i-start)) > 16) /*if the total bits saved is more than header*/ { /*check if we are going to reduce bits in the near future (before the current savings is realized)*/ for(j=start+1;j<=i;j++) { ind = j-cache_start; if(bits_for_element_cache[ind] < 0) { abs_element = buffer[j & mask]; if(abs_element < 0) abs_element *= -1; bits_for_element_cache[ind] = find_bits_needed(abs_element); } bits = bits_for_element_cache[ind]; if(better_to_chop_here_and_use_fewer_bits_for_future(bits, max_bits, buffer, bits_for_element_cache, cache_start, j, end, mask)) { /*going to chop in the future anyway, so don't chop here*/ return 0; } } return 1; } } return 0;}/* * write_chunk_to_file(): (compression) writes "shortpacked" data to a file. */intpack_and_write_chunk_to_file(buffer, start, num, bits, fp, mask)FOB *fp;short *buffer;int start;int num, bits;int mask; /*so the buffer can be a circular buffer (if ALL_ONES, just use linear buffer)*/{ int i,j,k; char *char_ptr; char temp_char; char temp_char2; short compressed_data[MAX_SEQUENCE_SIZE]; int els; short test_short = 1;/* printf("paw start %d num %d mask %d\n", start, num, mask);*/ els = pack_short_array_into_buffer(buffer, start, num, bits, mask, compressed_data); fputc((unsigned char) num, fp); fputc((unsigned char) bits, fp); if(ieee_order == -1) /*set this if not set already*/ { ieee_order = (htons(test_short) == test_short); } /* if the machine is NOT IEEE order, swap bytes of data before writing.*/ if (!ieee_order) { char_ptr = (char*)compressed_data; for(i=0;i<els;i++) { temp_char = *char_ptr; temp_char2 = *(char_ptr+1); *(char_ptr++) = temp_char2; *(char_ptr++) = temp_char; } } /* write the "shortpacked" data to file */ fwrite(compressed_data, sizeof(short), els, fp);}/* * read_shortpack_from_file(): (uncompression) read "shortpacked" data from a * file */intread_shortpack_chunk_from_file(fp, buffer, start, max_elements, mask)FOB *fp;short *buffer;int start, max_elements;int mask; /*so the buffer can be a circular buffer (if ALL_ONES, just use linear buffer)*/{ int i,j,k; int num_read; int num, bits_used, els; char *char_ptr; char temp_char; char temp_char2; int num_unpacked; short compressed_data[MAX_SEQUENCE_SIZE]; short test_short = 1; num = fgetc(fp); bits_used = fgetc(fp);/* printf(" num = %d, bits_used = %d\n",num,bits_used); printf(" num = %x, bits_used = %x\n",num,bits_used);*/ if (num < 0 || bits_used < 0){ return (-1); } els = (num * (bits_used + 1)) / 16.0; if ((num * (bits_used + 1)) % 16 != 0) els++;/* printf(" els = %d\n",els); */ num_read = fread(compressed_data, sizeof(short), els, fp);/* printf("num_read %d != els %d\n", num_read,els); printf("read_shortpack_chunk_from_file: it's ok\n"); printf(" num_read %d eld %d! num %d bits_used %d start %d max %d\n", num_read, els, num, bits_used, start, max_elements); */ if(num_read != els) { printf("read_shortpack_chunk_from_file: HEY! something is seriously wrong! maybe you\n"); printf(" are trying to read a non-shortpacked file with a shortpack reading\n"); printf(" routine num_read %d eld %d! num %d bits_used %d start %d max %d\n", num_read, els, num, bits_used, start, max_elements); els = num_read; exit(-1); } if(ieee_order == -1) /*set this if not set already*/ { ieee_order = (htons(test_short) == test_short); } /* * If this machinee does not follow IEEE byte swapping, swap the input bytes here */ if (!ieee_order) { char_ptr = (char*)compressed_data; for(i=0;i<els;i++) { temp_char = *char_ptr; temp_char2 = *(char_ptr+1); *(char_ptr++) = temp_char2; *(char_ptr++) = temp_char; } } num_unpacked = unpack_short_array_into_buffer(buffer, start, max_elements, bits_used, mask, compressed_data, num); return num_unpacked;}pack_short_array_into_buffer(buffer, start, num, bits, mask, compressed_data)short *buffer;int num, bits, mask;short *compressed_data;{ int i,j,k; int bit_mark; int buffer_ind; int els; short v;/* printf("psa:start %d num %d mask %d\n", start, num, mask);*/ els = (num * (bits + 1)) / 16.0; if ((num * (bits + 1)) % 16 != 0) els++;/* printf("psa:els %d\n", els);*/ for(j=0;j<els;j++) compressed_data[j] = 0; j = 0; bit_mark = 0; for (i = 0; i < num; i++) { buffer_ind = (start+i) & mask; v = buffer[buffer_ind]; /* set the sign here */ bit_mark++; if (v < 0) { compressed_data[j] |= log2s[16 - bit_mark]; v = -v; } if (bit_mark == 16) { bit_mark = 0; j++; } for (k = bits - 1; k >= 0; k--) { bit_mark++; if ((v & log2s[k]) != 0) compressed_data[j] |= log2s[16 - bit_mark]; if (bit_mark == 16) { bit_mark = 0; j++; } } } if(bit_mark == 0)return j; else return (j+1);}unpack_short_array_into_buffer(buffer, start, max_elements, bits, mask, compressed_data, num)short *buffer;int start, max_elements;int mask;short *compressed_data;int num, bits;{ int i, k; char negative; register short *log2s_ptr; register short *log2s_stop_ptr; short *log2s_start_ptr; register short temp_out; register short *logs2_kptr; int buffer_ind; register short temp_short; short *buf_ptr; buf_ptr = compressed_data; temp_short = *buf_ptr++; log2s_ptr = log2s_start_ptr = &(log2s[15]); log2s_stop_ptr = log2s; for (i = 0; i < num; i++) { if((start + i) >= max_elements) { printf("unpack_short_array_into_buffer:HEY! something seems wrong - ran out of space in buffer!! (just truncating)\n"); return i; } buffer_ind = (start+i) & mask; temp_out = 0; negative = ((temp_short & *(log2s_ptr--)) != 0); if (log2s_ptr < log2s_stop_ptr) { log2s_ptr = log2s_start_ptr; temp_short = *(buf_ptr++); } logs2_kptr = &(log2s[bits - 1]); for (k = bits + 1; (--k) > 0;) { if ((temp_short & *(log2s_ptr--)) != 0) temp_out |= *logs2_kptr; logs2_kptr--; if (log2s_ptr < log2s_stop_ptr) { log2s_ptr = log2s_start_ptr; temp_short = *(buf_ptr++); } } if (negative) if (temp_out != 0) buffer[buffer_ind] = -temp_out; else buffer[buffer_ind] = 32768; else buffer[buffer_ind] = temp_out; } return num;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -