/* * This routine will determine the location of a block of data * in the hyper cube. Basically this does an index calculation * for an n dimensional cube. */ static byte * cube_ptr_from_index(gs_function_Sd_params_t * params, int indexes[]) { int i, sum = indexes[params->m - 1]; for (i = params->m - 2; i >= 0; i--) { sum *= params->Size[i]; sum += indexes[i]; } return (byte *)(params->DataSource.data.str.data) + sum * params->n * bits2bytes(params->BitsPerSample); }
/** * @name addrCpy * * @brief Copies the given number of bits. * * @param[in] dst Pointer to the destination bit string * @param[in] src Pointer to the source bit string * @param[in] nBits The number of bits to be copied */ static inline void addrCpy (void* dst, void* src, u32 nBits) { u32 nBytes; u32 len; u32 n; nBytes = bits2bytes(nBits); len = nBytes << 3; n = (len > nBits) ? (nBytes - 1) : nBytes; memcpy(dst, src, n); if (n < nBytes) { ((u8*)dst)[n] = ((u8*)src)[n] & (~((1 << (len - nBits)) - 1)); } }
int main(int argc, char *argv[]) { decoder_t *D=NULL; /* pointer to decoding table */ int current_size=0; /* current decode table capacity */ int nstrings=0; /* current decode table actual size */ char extension; /* one extension character */ int copystring; /* index of the string it builds on */ char dummybyte; /* reads the newline at end of each line */ int i_bits=0, o_bytes=0; /* count of input bits (estimated) and output bytes (exact) */ /* create initial decode array */ D = (decoder_t*)malloc(INITSIZE*sizeof(*D)); current_size = INITSIZE; assert(D); /* and insert the first string, the empty string */ D[0].extension = '\0'; D[0].copystring = 0; nstrings = 1; /* now process extension,copystring pairs from the input */ while ((extension=getchar()) != EOF) { /* have got the extension character, so there really should be a matching copystring value and then a newline */ assert(scanf("%d%c", ©string, &dummybyte)==2); assert(copystring>=0 && copystring<=nstrings); #if DEBUG printf("DB: extension = %c, copystring = %d\n", extension, copystring); #endif /* check if decode array has enough space */ if (nstrings==current_size) { /* and if not, extend it */ current_size *= MULTIPLY; D = (decoder_t*)realloc(D, current_size*sizeof(*D)); assert(D); #if DEBUG printf("DB: D now %d entries\n", current_size); #endif } /* add the new string to the decode array */ assert(nstrings<current_size); D[nstrings].extension = extension; D[nstrings].copystring = copystring; /* and then print out the string it represents, return value indicayes how long it was */ o_bytes += rec_print(D, nstrings); /* and how many bit could the two inputs have fitted in to? */ i_bits += EXTENSION_BITS + comp_len(nstrings); #if DEBUG printf("\n"); #endif /* and finally, now ready to iterate with a new phrase installed in the dictionary */ nstrings++; } /* print some final summary statistics to the screen, but first make sure that all of the stdout output has been emitted */ fflush(stdout); fprintf(stderr, "\n"); fprintf(stderr, "decode: %6d factors processed\n", nstrings-1); fprintf(stderr, "decode: %6d bytes output\n", o_bytes); fprintf(stderr, "decode: %6d bits = %5d bytes sufficient as input\n", i_bits, bits2bytes(i_bits)); fprintf(stderr, "decode: %6.3f bits/byte achieved by encoder\n", 1.0*i_bits/o_bytes); /* not strictly necessary to do this, but good housekeeping habit */ free(D); D = NULL; return 0; }
int make_sampled_function(i_ctx_t * i_ctx_p, ref *arr, ref *pproc, gs_function_t **func) { int code = 0, *ptr, i, total_size, num_components, CIESubst; byte * bytes = 0; float *fptr; gs_function_t *pfn = *func; gs_function_Sd_params_t params = {0}; ref alternatespace, *palternatespace = &alternatespace; PS_colour_space_t *space, *altspace; code = get_space_object(i_ctx_p, arr, &space); if (code < 0) return code; if (!space->alternateproc) return e_typecheck; code = space->alternateproc(i_ctx_p, arr, &palternatespace, &CIESubst); if (code < 0) return code; code = get_space_object(i_ctx_p, palternatespace, &altspace); if (code < 0) return code; /* * Set up the hyper cube function data structure. */ params.Order = 3; params.BitsPerSample = 16; code = space->numcomponents(i_ctx_p, arr, &num_components); if (code < 0) return code; fptr = (float *)gs_alloc_byte_array(imemory, num_components * 2, sizeof(float), "make_sampled_function(Domain)"); if (!fptr) return e_VMerror; code = space->domain(i_ctx_p, arr, fptr); if (code < 0) { gs_free_const_object(imemory, fptr, "make_sampled_function(Domain)"); return code; } params.Domain = fptr; params.m = num_components; code = altspace->numcomponents(i_ctx_p, palternatespace, &num_components); if (code < 0) { gs_free_const_object(imemory, params.Domain, "make_type4_function(Domain)"); return code; } fptr = (float *)gs_alloc_byte_array(imemory, num_components * 2, sizeof(float), "make_sampled_function(Range)"); if (!fptr) { gs_free_const_object(imemory, params.Domain, "make_sampled_function(Domain)"); return e_VMerror; } code = altspace->range(i_ctx_p, palternatespace, fptr); if (code < 0) { gs_free_const_object(imemory, params.Domain, "make_sampled_function(Domain)"); gs_free_const_object(imemory, fptr, "make_sampled_function(Range)"); return code; } params.Range = fptr; params.n = num_components; /* * The Size array may or not be specified. If it is not specified then * we need to determine a set of default values for the Size array. */ ptr = (int *)gs_alloc_byte_array(imemory, params.m, sizeof(int), "Size"); if (ptr == NULL) { code = gs_note_error(e_VMerror); goto fail; } params.Size = ptr; /* * Determine a default * set of values. */ code = determine_sampled_data_size(params.m, params.n, params.BitsPerSample, (int *)params.Size); if (code < 0) goto fail; /* * Determine space required for the sample data storage. */ total_size = params.n * bits2bytes(params.BitsPerSample); for (i = 0; i < params.m; i++) total_size *= params.Size[i]; /* * Allocate space for the data cube itself. */ bytes = gs_alloc_byte_array(imemory, total_size, 1, "cube_build_func0(bytes)"); if (!bytes) { code = gs_note_error(e_VMerror); goto fail; } data_source_init_bytes(¶ms.DataSource, (const unsigned char *)bytes, total_size); /* * This is temporary. We will call gs_function_Sd_init again after * we have collected the cube data. We are doing it now because we need * a function structure created (along with its GC enumeration stuff) * that we can use while collecting the cube data. We will call * the routine again after the cube data is collected to correctly * initialize the function. */ code = gs_function_Sd_init(&pfn, ¶ms, imemory); if (code < 0) return code; /* * Now setup to collect the sample data. */ return sampled_data_setup(i_ctx_p, pfn, pproc, sampled_data_finish, imemory); fail: gs_function_Sd_free_params(¶ms, imemory); return (code < 0 ? code : gs_note_error(e_rangecheck)); }
/* * Continuation procedure for processing sampled values. */ static int sampled_data_continue(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_sampled_data_enum *penum = senum; gs_function_Sd_params_t * params = (gs_function_Sd_params_t *)&penum->pfn->params; int i, j, num_out = params->n; int code = 0; byte * data_ptr; double sampled_data_value_max = (double)((1 << params->BitsPerSample) - 1); int bps = bits2bytes(params->BitsPerSample), stack_depth_adjust = 0; /* * Check to make sure that the procedure produced the correct number of * values. If not, move the stack back to where it belongs and abort */ if (num_out + O_STACK_PAD + penum->o_stack_depth != ref_stack_count(&o_stack)) { stack_depth_adjust = ref_stack_count(&o_stack) - penum->o_stack_depth; if (stack_depth_adjust < 0) { /* * If we get to here then there were major problems. The function * removed too many items off of the stack. We had placed extra * (unused) stack stack space to allow for this but the function * exceeded even that. Data on the stack may have been lost. * The only thing that we can do is move the stack pointer back and * hope. (We have not seen real Postscript files that have this * problem.) */ push(-stack_depth_adjust); ifree_object(penum->pfn, "sampled_data_continue(pfn)"); ifree_object(penum, "sampled_data_continue((enum)"); return_error(e_undefinedresult); } } /* Save data from the given function */ data_ptr = cube_ptr_from_index(params, penum->indexes); for (i=0; i < num_out; i++) { ulong cv; double value; double rmin = params->Range[2 * i]; double rmax = params->Range[2 * i + 1]; code = real_param(op + i - num_out + 1, &value); if (code < 0) return code; if (value < rmin) value = rmin; else if (value > rmax) value = rmax; value = (value - rmin) / (rmax - rmin); /* Convert to 0 to 1.0 */ cv = (int) (value * sampled_data_value_max + 0.5); for (j = 0; j < bps; j++) data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8)); /* MSB first */ } pop(num_out); /* Move op to base of result values */ /* Check if we are done collecting data. */ if (increment_cube_indexes(params, penum->indexes)) { if (stack_depth_adjust == 0) pop(O_STACK_PAD); /* Remove spare stack space */ else pop(stack_depth_adjust - num_out); /* Execute the closing procedure, if given */ code = 0; if (esp_finish_proc != 0) code = esp_finish_proc(i_ctx_p); return code; } else { if (stack_depth_adjust) { stack_depth_adjust -= num_out; push(O_STACK_PAD - stack_depth_adjust); for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) make_null(op - i); } } /* Now get the data for the next location */ return sampled_data_sample(i_ctx_p); }
/* * Fill in the data for a function type 0 parameter object to be used while * we collect the data for the data cube. At the end of the process, we * will create a function type 0 object to be used to calculate values * as a replacement for the original function. */ static int cube_build_func0(const ref * pdict, gs_function_Sd_params_t * params, gs_memory_t *mem) { byte * bytes = 0; int code, i; int total_size; if ((code = dict_int_param(pdict, "Order", 1, 3, 1, ¶ms->Order)) < 0 || (code = dict_int_param(pdict, "BitsPerSample", 1, 32, 0, ¶ms->BitsPerSample)) < 0 || ((code = params->m = fn_build_float_array(pdict, "Domain", false, true, ¶ms->Domain, mem)) < 0 ) || ((code = params->n = fn_build_float_array(pdict, "Range", false, true, ¶ms->Range, mem)) < 0) ) { goto fail; } /* * The previous logic set the size of m and n to the size of the Domain * and Range arrays. This is twice the actual size. Correct this and * check for valid values. */ params->m >>= 1; params->n >>= 1; if (params->m == 0 || params->n == 0 || params->m > MAX_NUM_INPUTS || params->n > MAX_NUM_OUTPUTS) { code = gs_note_error(e_rangecheck); goto fail; } /* * The Size array may or not be specified. If it is not specified then * we need to determine a set of default values for the Size array. */ { int *ptr = (int *) gs_alloc_byte_array(mem, params->m, sizeof(int), "Size"); if (ptr == NULL) { code = gs_note_error(e_VMerror); goto fail; } params->Size = ptr; code = dict_ints_param(mem, pdict, "Size", params->m, ptr); if (code < 0) goto fail; if (code == 0) { /* * The Size array has not been specified. Determine a default * set of values. */ code = determine_sampled_data_size(params->m, params->n, params->BitsPerSample, (int *)params->Size); if (code < 0) goto fail; } else { /* Size array specified - verify valid */ if (code != params->m || !valid_cube_size(params->m, params->n, params->BitsPerSample, params->Size)) code = gs_note_error(e_rangecheck); goto fail; } } /* * Determine space required for the sample data storage. */ total_size = params->n * bits2bytes(params->BitsPerSample); for (i = 0; i < params->m; i++) total_size *= params->Size[i]; /* * Allocate space for the data cube itself. */ bytes = gs_alloc_byte_array(mem, total_size, 1, "cube_build_func0(bytes)"); if (!bytes) { code = gs_note_error(e_VMerror); goto fail; } data_source_init_bytes(¶ms->DataSource, (const unsigned char *)bytes, total_size); return 0; fail: gs_function_Sd_free_params(params, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }