Exemple #1
0
void *iw_realloc(const char *file, unsigned int line, void *ptr, size_t size) {
    if(!iw_memory_tracking) {
        return realloc(ptr, size);
    }

    void *new_chunk = NULL;

    // TODO: To simplify realloc we just allocate a new memory chunk and free the
    // old one.
    if(size != 0) {
        new_chunk = iw_malloc(file, line, size);
        if(new_chunk == NULL) {
            // Realloc does not free or move the old memory if allocation fails.
            return NULL;
        }
    }

    if(ptr != NULL) {
        if(new_chunk != NULL) {
            void *len_ptr = ptr - PRE_GUARD_SIZE - LEN_SIZE;
            unsigned int len = ntohl(*(unsigned int *)len_ptr);
            memcpy(new_chunk, ptr, len);
        }
        iw_free(ptr);
    }

    return new_chunk;
}
Exemple #2
0
// Allocate a large block of memory, presumably for image data.
// Use this if integer overflow is a possibility when multiplying
// two factors together.
void *iw_malloc_large(struct iw_context *ctx, size_t n1, size_t n2)
{
	if(n1 > ctx->max_malloc/n2) {
		iw_seterror(ctx,iwcore_get_string(ctx,iws_image_too_large));
		return NULL;
	}
	return iw_malloc(ctx,n1*n2);
}
Exemple #3
0
char *iw_strdup(const char *file, unsigned int line, const char *ptr) {
    if(!iw_memory_tracking) {
        return strdup(ptr);
    }

    int len = strlen(ptr) + 1;
    void *chunk = iw_malloc(file, line, len);
    if(chunk == NULL) {
        return NULL;
    }
    memcpy(chunk, ptr, len + 1);
    return chunk;
}
Exemple #4
0
void *iw_calloc(const char *file, unsigned int line, int elems, size_t size) {
    if(!iw_memory_tracking) {
        return calloc(elems, size);
    }

    void *chunk = iw_malloc(file, line, elems * size);
    if(chunk == NULL) {
        return NULL;
    }

    memset(chunk, 0, size);
    return chunk;
}
Exemple #5
0
int iw_file_to_memory(struct iw_context *ctx, struct iw_iodescr *iodescr,
  void **pmem, size_t *psize)
{
	int ret;
	size_t bytesread;

	*pmem=NULL;
	*psize=0;

	if(!iodescr->getfilesize_fn) return 0;

	ret = (*iodescr->getfilesize_fn)(ctx,iodescr,psize);
	if(!ret) return 0;

	*pmem = iw_malloc(ctx,*psize);

	ret = (*iodescr->read_fn)(ctx,iodescr,*pmem,*psize,&bytesread);
	if(!ret) return 0;
	if(bytesread != *psize) return 0;
	return 1;
}
Exemple #6
0
// Optimize to palette, or 1-, 2-, or 4-bpp grayscale.
static void iwopt_try_pal_lowgray_optimization(struct iw_context *ctx, struct iw_opt_ctx *optctx)
{
	int ret;
	int binary_trns;
	unsigned int trns_shade;

	if(!(ctx->output_profile&IW_PROFILE_PAL1) &&
	   !(ctx->output_profile&IW_PROFILE_PAL2) &&
	   !(ctx->output_profile&IW_PROFILE_PAL4) &&
	   !(ctx->output_profile&IW_PROFILE_PAL8) &&
	   !(ctx->output_profile&IW_PROFILE_GRAY1) &&
	   !(ctx->output_profile&IW_PROFILE_GRAY2) &&
	   !(ctx->output_profile&IW_PROFILE_GRAY4) )
	{
		// Output format doesn't support anything that this optimization can provide.
		return;
	}

	if(optctx->bit_depth!=8) {
		// Palettes aren't supported with bitdepth>8.
		return;
	}

	optctx->palette = iw_malloc(ctx,sizeof(struct iw_palette));
	if(!optctx->palette) return;

	optctx->palette->num_entries=0;

	ret = optctx_collect_palette_colors(ctx,optctx);
	if(!ret) {
		// Image can't be converted to a palette image.
		goto done;
	}

	// optctx->palette now contains a palette that can be used.

	// For images that have at most 256 (8-bit-compatible) colors, the order
	// of preference is gray1, pal1, gray2, pal2, gray4, pal4, gray8, pal8.

	if(ctx->opt_grayscale && (ctx->output_profile&IW_PROFILE_GRAY1) && iwopt_palette_is_valid_gray(ctx,optctx,1,&binary_trns,&trns_shade)) {
		// Replace the palette with a fully-populated grayscale palette.
		// The palette might already be correct, but it might not be.
		// It will be missing any gray shade that wasn't in the image.
		iwopt_make_gray_palette(ctx,optctx,1);
		if(binary_trns) {
			optctx->has_colorkey_trns = 1;
			optctx->colorkey_r = optctx->colorkey_b = optctx->colorkey_g = trns_shade;
		}
	}
	else if(iwopt_palette_opt_ok(ctx,optctx,1)) {
		;
	}
	else if(ctx->opt_grayscale && (ctx->output_profile&IW_PROFILE_GRAY2) && iwopt_palette_is_valid_gray(ctx,optctx,2,&binary_trns,&trns_shade)) {
		iwopt_make_gray_palette(ctx,optctx,2);
		if(binary_trns) {
			optctx->has_colorkey_trns = 1;
			optctx->colorkey_r = optctx->colorkey_b = optctx->colorkey_g = trns_shade;
		}
	}
	else if(iwopt_palette_opt_ok(ctx,optctx,2)) {
		;
	}
	else if(ctx->opt_grayscale && (ctx->output_profile&IW_PROFILE_GRAY4) && iwopt_palette_is_valid_gray(ctx,optctx,4,&binary_trns,&trns_shade)) {
		iwopt_make_gray_palette(ctx,optctx,4);
		if(binary_trns) {
			optctx->has_colorkey_trns = 1;
			optctx->colorkey_r = optctx->colorkey_b = optctx->colorkey_g = trns_shade;
		}
	}
	else if(iwopt_palette_opt_ok(ctx,optctx,4)) {
		;
	}
	else if(ctx->opt_grayscale && (ctx->output_profile&IW_PROFILE_GRAYSCALE) && iwopt_palette_is_valid_gray(ctx,optctx,8,&binary_trns,&trns_shade)) {
		// This image can best be encoded as 8-bit grayscale. We don't handle that here.
		goto done;
	}
	else if(iwopt_palette_opt_ok(ctx,optctx,8)) {
		;
	}
	else {
		// Found no optimizations that we can perform.
		goto done;
	}

	if(!optctx->palette_is_grayscale) {
		// Sort the palette
		qsort((void*)optctx->palette->entry,optctx->palette->num_entries,
			sizeof(struct iw_rgba8color),iwopt_palsortfunc);
	}

	iwopt_convert_to_palette_image(ctx,optctx);

done:
	if(optctx->imgtype!=IW_IMGTYPE_PALETTE) {
		iw_free(optctx->palette);
		optctx->palette = NULL;
	}
}