Exemplo n.º 1
0
/*
 * 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);
}
Exemplo n.º 2
0
/**
 * @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));
    }
}
Exemplo n.º 3
0
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", &copystring, &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;
}
Exemplo n.º 4
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(&params.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, &params, 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(&params, imemory);
    return (code < 0 ? code : gs_note_error(e_rangecheck));
}
Exemplo n.º 5
0
/*
 * 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);
}
Exemplo n.º 6
0
/*
 * 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, &params->Order)) < 0 ||
        (code = dict_int_param(pdict, "BitsPerSample", 1, 32, 0,
                               &params->BitsPerSample)) < 0 ||
        ((code = params->m =
            fn_build_float_array(pdict, "Domain", false, true,
                                        &params->Domain, mem)) < 0 ) ||
        ((code = params->n =
            fn_build_float_array(pdict, "Range", false, true,
                                        &params->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(&params->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));
}