Exemplo n.º 1
0
int stackBlurComponent(float* radius, unsigned char* srcComponent, int* width, int* height, unsigned char* dstComponent) {
	int size = (*width) * (*height);
	unsigned char* srcComponentCopy;
	int returnCode = newUnsignedCharArray(size, &srcComponentCopy);
	if (returnCode != MEMORY_OK) {
		return returnCode;
	}

	int i;
	memcpy(srcComponentCopy, srcComponent, size);
	for (i = 3; i--; ) {
		//horizontal pass
		returnCode = fastBlurComponent((int)(*radius), srcComponentCopy, *width, *height, dstComponent);
		if (returnCode != MEMORY_OK) {
			freeUnsignedCharArray(&srcComponentCopy);
			return returnCode;
		}
		//vertical pass
		returnCode = fastBlurComponent((int)(*radius), dstComponent, *height, *width, srcComponentCopy);
		if (returnCode != MEMORY_OK) {
			freeUnsignedCharArray(&srcComponentCopy);
			return returnCode;
		}
	}
	memcpy(dstComponent, srcComponentCopy, size);
	freeUnsignedCharArray(&srcComponentCopy);

	return MEMORY_OK;
}
Exemplo n.º 2
0
void deleteBitmap(Bitmap* bitmap) {
	freeUnsignedCharArray(&(*bitmap).red);
	freeUnsignedCharArray(&(*bitmap).green);
	freeUnsignedCharArray(&(*bitmap).blue);
	freeUnsignedCharArray(&(*bitmap).transformList.transforms);
	(*bitmap).transformList.size = 0;
	(*bitmap).width = 0;
	(*bitmap).height = 0;
}
Exemplo n.º 3
0
int stackBlur(float* radius, unsigned char* srcRed, unsigned char* srcGreen, unsigned char* srcBlue, int* width, int* height,
		unsigned char* dstRed, unsigned char* dstGreen, unsigned char* dstBlue) {
	unsigned int size = (*width) * (*height);

	unsigned char* srcComponentCopy;
	int returnCode = newUnsignedCharArray(size, &srcComponentCopy);
	if (returnCode != MEMORY_OK) {
		return returnCode;
	}

	unsigned int i, c;
	unsigned char* srcComponent;
	unsigned char* dstComponent;
	for (c = 3; c--; ) {
		if (c == 0) {
			srcComponent = srcRed;
			dstComponent = dstRed;
		} else if (c == 1) {
			srcComponent = srcGreen;
			dstComponent = dstGreen;
		} else {
			srcComponent = srcBlue;
			dstComponent = dstBlue;
		}

		memcpy(srcComponentCopy, srcComponent, size);
		for (i = 3; i--; ) {
			//horizontal pass
			returnCode = fastBlurComponent((int)(*radius), srcComponentCopy, *width, *height, dstComponent);
			if (returnCode != MEMORY_OK) {
				freeUnsignedCharArray(&srcComponentCopy);
				return returnCode;
			}
			//vertical pass
			returnCode = fastBlurComponent((int)(*radius), dstComponent, *height, *width, srcComponentCopy);
			if (returnCode != MEMORY_OK) {
				freeUnsignedCharArray(&srcComponentCopy);
				return returnCode;
			}
		}
		memcpy(dstComponent, srcComponentCopy, size);
	}
	freeUnsignedCharArray(&srcComponentCopy);
	return MEMORY_OK;
}
Exemplo n.º 4
0
int resizeChannel(unsigned char** channelPixels, int srcWidth, int srcHeight, int maxWidth, int maxHeight) {
	// Resize channel
	if (srcWidth > maxWidth && srcHeight > maxHeight) {
		unsigned char* scaledPixels;
		int returnCode = newUnsignedCharArray(maxWidth * maxHeight, &scaledPixels);
		if (returnCode != MEMORY_OK) {
			freeUnsignedCharArray(&scaledPixels);
			return returnCode;
		}
		returnCode = resizeChannelBicubic(*channelPixels, srcWidth, srcHeight, scaledPixels, maxWidth, maxHeight);
		if (returnCode != MEMORY_OK) {
			freeUnsignedCharArray(&scaledPixels);
			return returnCode;
		}
		//No need for hi-res channel so free the memory
		freeUnsignedCharArray(channelPixels); //channelPixels is already a pointer to a pointer

		*channelPixels = scaledPixels;
	}

	return MEMORY_OK;
}
Exemplo n.º 5
0
int Java_editimage_fliter_PhotoProcessing_nativeResizeBitmap(JNIEnv *env, jobject thiz,
															 jint newWidth, jint newHeight) {
	unsigned char* newRed;
	int resultCode = newUnsignedCharArray(newWidth*newHeight, &newRed);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resizeChannelBicubic(bitmap.red, bitmap.width, bitmap.height, newRed, (int)newWidth, (int)newHeight);
	freeUnsignedCharArray(&bitmap.red);
	bitmap.red = newRed;
	bitmap.redWidth = newWidth;
	bitmap.redHeight = newHeight;

	unsigned char* newGreen;
	resultCode = newUnsignedCharArray(newWidth*newHeight, &newGreen);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resizeChannelBicubic(bitmap.green, bitmap.width, bitmap.height, newGreen, (int)newWidth, (int)newHeight);
	freeUnsignedCharArray(&bitmap.green);
	bitmap.green = newGreen;
	bitmap.greenWidth = newWidth;
	bitmap.greenHeight = newHeight;

	unsigned char* newBlue;
	resultCode = newUnsignedCharArray(newWidth*newHeight, &newBlue);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resizeChannelBicubic(bitmap.blue, bitmap.width, bitmap.height, newBlue, (int)newWidth, (int)newHeight);
	freeUnsignedCharArray(&bitmap.blue);
	bitmap.blue = newBlue;
	bitmap.blueWidth = newWidth;
	bitmap.blueHeight = newHeight;

	bitmap.width = newWidth;
	bitmap.height = newHeight;
}
Exemplo n.º 6
0
//TODO memory usage may be reduced by using component based blur
int applyHDR(Bitmap* bitmap) {
	//Cache to local variables
	unsigned char* red = (*bitmap).red;
	unsigned char* green = (*bitmap).green;
	unsigned char* blue = (*bitmap).blue;

	unsigned char* blurRed;
	unsigned char* blurGreen;
	unsigned char* blurBlue;
	int length = (*bitmap).width * (*bitmap).height;
	int resultCode = newUnsignedCharArray(length, &blurRed);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurGreen);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		return resultCode;
	}
	float blurRadius = 9.0f;
	resultCode = stackBlur(&blurRadius, red, green, blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		freeUnsignedCharArray(&blurBlue);
		return resultCode;
	}

	unsigned int i, j;
	unsigned char r1, g1, b1, r2, g2, b2;
	float matrix[4][4];
	identMatrix(matrix);
	float saturation = 1.3f;
	saturateMatrix(matrix, &saturation);
	for (i = length; i--;) {
		// invert the blurred pixel
		r1 = 255 - blurRed[i];
		g1 = 255 - blurGreen[i];
		b1 = 255 - blurBlue[i];

		// Grain merge the inverted blurred pixel with the original
		r1 = grainMergePixelsComponent(r1, red[i]);
		g1 = grainMergePixelsComponent(g1, green[i]);
		b1 = grainMergePixelsComponent(b1, blue[i]);

		// boost the saturation of the original pixel
		//HSBColour hsb;
		//rgbToHsb(red[i], green[i], blue[i], &hsb);
		//hsb.s = min(1.0f, hsb.s * 1.3f);
		r2 = red[i];
		g2 = green[i];
		b2 = blue[i];
		applyMatrixToPixel(&r2, &g2, &b2, matrix);
		//hsbToRgb(&hsb, &r2, &g2, &b2);

		// grain merge the saturated pixel with the inverted grain merged pixel
		red[i] = grainMergePixelsComponent(r2, r1);
		green[i] = grainMergePixelsComponent(g2, g1);
		blue[i] = grainMergePixelsComponent(b2, g1);
	}

	applyMatrix(bitmap, matrix);

	freeUnsignedCharArray(&blurRed);
	freeUnsignedCharArray(&blurGreen);
	freeUnsignedCharArray(&blurBlue);

	return MEMORY_OK;
}
Exemplo n.º 7
0
int applySahara(Bitmap* bitmap) {
	int length = (*bitmap).width * (*bitmap).height;
	int i;
	unsigned char r, g, b;

	//HSBColour hsb;
	unsigned char* red = (*bitmap).red;
	unsigned char* green = (*bitmap).green;
	unsigned char* blue = (*bitmap).blue;
	unsigned char brightnessLut[256];
	unsigned char contrastLut[256];
	for (i = 0; i < 256; i++) {
		float pixelf = i/255.0f;
		//brightnessLut[i] = 255*applyBrightnessToPixelComponent(pixelf, 0.35433f);
		//contrastLut[i] = 255*applyContrastToPixelComponent(pixelf, 0.1496f);
		brightnessLut[i] = 255*applyBrightnessToPixelComponent(pixelf, 0.45f);
		contrastLut[i] = 255*applyContrastToPixelComponent(pixelf, 0.1f);
	}
	for (i = length; i--; ) {
		r = brightnessLut[red[i]];
		g = brightnessLut[green[i]];
		b = brightnessLut[blue[i]];

		r = contrastLut[r];
		green[i] = contrastLut[g];
		b = contrastLut[b];

		red[i] = (r*0.8431f/*215*/)+40; //compress the red channel between 18 - 237
		blue[i] = (b*0.8823f/*225*/)+30; //compress the blue channel between 50 - 205

		//rgbToHsb(red[i], green[i], blue[i], &hsb);
		//hsb.s = hsb.s * 0.55f;

		//hsbToRgb(&hsb, &red[i], &green[i], &blue[i]);
	}

	float matrix[4][4];
	identMatrix(matrix);
	float saturation = 0.65f;
	saturateMatrix(matrix, &saturation);
	applyMatrix(bitmap, matrix);

	unsigned char* blurRed;
	unsigned char* blurGreen;
	unsigned char* blurBlue;
	int resultCode = newUnsignedCharArray(length, &blurRed);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurGreen);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		return resultCode;
	}

	float blurRadius = 1.0f;
	resultCode = stackBlur(&blurRadius, (*bitmap).red, (*bitmap).green, (*bitmap).blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		freeUnsignedCharArray(&blurBlue);
		return resultCode;
	}

	short int overlayLut[256][256];
	unsigned char multiplyLut255[256];
	unsigned char multiplyLut227[256];
	unsigned char multiplyLut187[256];
	unsigned int j;
	for (i = 0; i < 256; i++) {
		for (j = 0; j < 256; j++) {
			overlayLut[i][j] = -1;//overlayPixelComponents(i, j, 1.0f);
		}
		multiplyLut255[i] = multiplyPixelComponents(255, i);
		multiplyLut227[i] = multiplyPixelComponents(227, i);
		multiplyLut187[i] = multiplyPixelComponents(187, i);
	}
	for (i = length; i--; ) {
		if (overlayLut[blurRed[i]][red[i]] == -1) {
			overlayLut[blurRed[i]][red[i]] = overlayPixelComponents(blurRed[i], red[i], 1.0f);
		}
		red[i] = overlayLut[blurRed[i]][red[i]];//overlayPixelComponents(blurRed[i], red[i], 1.0f);

		if (overlayLut[blurGreen[i]][green[i]] == -1) {
			overlayLut[blurGreen[i]][green[i]] = overlayPixelComponents(blurGreen[i], green[i], 1.0f);
		}
		green[i] = overlayLut[blurGreen[i]][green[i]];//overlayPixelComponents(blurGreen[i], green[i], 1.0f);

		if (overlayLut[blurBlue[i]][blue[i]] == -1) {
			overlayLut[blurBlue[i]][blue[i]] = overlayPixelComponents(blurBlue[i], blue[i], 1.0f);
		}
		blue[i] = overlayLut[blurBlue[i]][blue[i]];//overlayPixelComponents(blurBlue[i], blue[i], 1.0f);

		// Multiply by a wheat colour rgb(255, 227, 187)
		red[i] = multiplyLut255[red[i]];//multiplyPixelComponents(255, red[i]);
		green[i] = multiplyLut227[green[i]];//multiplyPixelComponents(227, green[i]);
		blue[i] = multiplyLut187[blue[i]];//multiplyPixelComponents(187, blue[i]);
	}

	freeUnsignedCharArray(&blurRed);
	freeUnsignedCharArray(&blurGreen);
	freeUnsignedCharArray(&blurBlue);

	return MEMORY_OK;
}
Exemplo n.º 8
0
// amount is 0.0 to 1.0
// threshold is 0 to 255
int unsharpMask(Bitmap* bitmap, int radius, float amount, int threshold) {
	unsigned char* red = (*bitmap).red;
	unsigned char* green = (*bitmap).green;
	unsigned char* blue = (*bitmap).blue;
	unsigned int length = (*bitmap).width * (*bitmap).height;

	// Create blur
	unsigned char* blurRed;
	unsigned char* blurGreen;
	unsigned char* blurBlue;
	int resultCode = newUnsignedCharArray(length, &blurRed);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurGreen);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		return resultCode;
	}
	resultCode = newUnsignedCharArray(length, &blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		return resultCode;
	}

	float blurRadius = radius/3.0f;
	resultCode = stackBlur(&blurRadius, (*bitmap).red, (*bitmap).green, (*bitmap).blue, &((*bitmap).width), &((*bitmap).height), blurRed, blurGreen, blurBlue);
	if (resultCode != MEMORY_OK) {
		freeUnsignedCharArray(&blurRed);
		freeUnsignedCharArray(&blurGreen);
		freeUnsignedCharArray(&blurBlue);
		return resultCode;
	}

	int i, j;
	short int lut[256][256];
	float a = (4 * amount) + 1;
	for (i = 0; i < 256; i++) {
		for (j = 0; j < 256; j++) {
			lut[i][j] = -1;//clampComponent((int) (a * (i - j) + j));
		}
	}
	for (i = length; i--;) {
		int r1 = red[i];
		int g1 = green[i];
		int b1 = blue[i];

		int r2 = blurRed[i];
		int g2 = blurGreen[i];
		int b2 = blurBlue[i];

		if (fabs(r1 - r2) >= threshold) {
			if (lut[r1][r2] == -1) {
				lut[r1][r2] = clampComponent((int) ((a + 1) * (r1 - r2) + r2));
			}
			r1 = lut[r1][r2]; //clampComponent((int) ((a + 1) * (r1 - r2) + r2));
		}
		if (fabs(g1 - g2) >= threshold) {
			if (lut[g1][g2] == -1) {
				lut[g1][g2] = clampComponent((int) ((a + 1) * (g1 - g2) + g2));
			}
			g1 = lut[g1][g2]; //clampComponent((int) ((a + 1) * (g1 - g2) + g2));
		}
		if (fabs(b1 - b2) >= threshold) {
			if (lut[b1][b2] == -1) {
				lut[b1][b2] = clampComponent((int) ((a + 1) * (b1 - b2) + b2));
			}
			b1 = lut[b1][b2]; //clampComponent((int) ((a + 1) * (b1 - b2) + b2));
		}

		red[i] = r1;
		green[i] = g1;
		blue[i] = b1;
	}

	freeUnsignedCharArray(&blurRed);
	freeUnsignedCharArray(&blurGreen);
	freeUnsignedCharArray(&blurBlue);
}
Exemplo n.º 9
0
int decodeJpegData(char* jpegData, int jpegSize, int maxPixels, Bitmap* bitmap) {
	int returnCode;

	int maxWidth;
	int maxHeight;

	// Decode red channel
	returnCode = decodeJpegChannel(jpegData, jpegSize, 0, &(*bitmap).red, &(*bitmap).redWidth, &(*bitmap).redHeight);
	if (returnCode != MEMORY_OK) {
		LOGE("Failed to decode red channel");
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		return returnCode;
	}

	doTransforms(bitmap, 1, 0, 0);
	// Resize red channel
	getScaledSize((*bitmap).redWidth, (*bitmap).redHeight, maxPixels, &maxWidth, &maxHeight); //We only need to do this once as r, g, b should be the same sizes
	returnCode = resizeChannel(&(*bitmap).red, (*bitmap).redWidth, (*bitmap).redHeight, maxWidth, maxHeight);
	if (returnCode != MEMORY_OK) {
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		return returnCode;
	}
	// Set red channel dimensions
	if ((*bitmap).redWidth >= maxWidth && (*bitmap).redHeight >= maxHeight) {
		(*bitmap).redWidth = maxWidth;
		(*bitmap).redHeight = maxHeight;
	}

	// Decode green channel
	returnCode = decodeJpegChannel(jpegData, jpegSize, 1, &(*bitmap).green, &(*bitmap).greenWidth, &(*bitmap).greenHeight);
	if (returnCode != MEMORY_OK) {
		LOGE("Failed to decode green channel");
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		freeUnsignedCharArray(&(*bitmap).green);
		return returnCode;
	}

	doTransforms(bitmap, 0, 1, 0);
	// Resize green channel
	returnCode = resizeChannel(&(*bitmap).green, (*bitmap).greenWidth, (*bitmap).greenHeight, maxWidth, maxHeight);
	if (returnCode != MEMORY_OK) {
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		freeUnsignedCharArray(&(*bitmap).green);
		return returnCode;
	}
	// Set green channel dimensions
	if ((*bitmap).greenWidth >= maxWidth && (*bitmap).greenHeight >= maxHeight) {
		(*bitmap).greenWidth = maxWidth;
		(*bitmap).greenHeight = maxHeight;
	}

	// Decode blue channel
	returnCode = decodeJpegChannel(jpegData, jpegSize, 2, &(*bitmap).blue, &(*bitmap).blueWidth, &(*bitmap).blueHeight);
	if (returnCode != MEMORY_OK) {
		LOGE("Failed to decode blue channel");
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		freeUnsignedCharArray(&(*bitmap).green);
		freeUnsignedCharArray(&(*bitmap).blue);
		return returnCode;
	}

	doTransforms(bitmap, 0, 0, 1);
	// Resize blue channel
	returnCode = resizeChannel(&(*bitmap).blue, (*bitmap).blueWidth, (*bitmap).blueHeight, maxWidth, maxHeight);
	if (returnCode != MEMORY_OK) {
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		freeUnsignedCharArray(&(*bitmap).green);
		freeUnsignedCharArray(&(*bitmap).blue);
		return returnCode;
	}
	// Set blue channel dimensions
	if ((*bitmap).blueWidth >= maxWidth && (*bitmap).blueHeight >= maxHeight) {
		(*bitmap).blueWidth = maxWidth;
		(*bitmap).blueHeight = maxHeight;
	}

	// Set the final bitmap dimensions
	if ((*bitmap).redWidth == (*bitmap).greenWidth && (*bitmap).redWidth == (*bitmap).blueWidth
			&& (*bitmap).redHeight == (*bitmap).greenHeight && (*bitmap).redHeight == (*bitmap).blueHeight) {
		(*bitmap).width = (*bitmap).redWidth;
		(*bitmap).height = (*bitmap).redHeight;
	} else {
		njDone();
		freeUnsignedCharArray(&(*bitmap).red);
		freeUnsignedCharArray(&(*bitmap).green);
		freeUnsignedCharArray(&(*bitmap).blue);
		return INCONSISTENT_BITMAP_ERROR;
	}

	njDoneLeaveRGBData();

	return MEMORY_OK;
}
Exemplo n.º 10
0
int resizeChannelBicubic(const unsigned char *src, int srcWidth, int srcHeight, unsigned char *dst, int dstWidth, int dstHeight) {
	unsigned char *xVector;
	int i, nextCol, nextRow, numRows, ty, x, y;
	double factor, *s, *scanline, *scaleScanline, *t, xScale, xSpan,
			yScale, ySpan, *yVector;

	factor = (double) dstWidth / (double) srcWidth;

	if (dst == NULL) {
		return -1;
	}

	/* No scaling needed. */
	if (srcWidth == dstWidth) {

		memcpy(dst, src, srcWidth * srcHeight);
		return 0;
	}

	int returnCode = newUnsignedCharArray(srcWidth, &xVector);
	if (returnCode != MEMORY_OK) {
		return returnCode;
	}

	returnCode = newDoubleArray(srcWidth, &yVector);
	if (returnCode != MEMORY_OK) {
		freeUnsignedCharArray(&xVector);
		return returnCode;
	}

	returnCode = newDoubleArray(srcWidth, &scanline);
	if (returnCode != MEMORY_OK) {
		freeUnsignedCharArray(&xVector);
		freeDoubleArray(&yVector);
		return returnCode;
	}

	returnCode = newDoubleArray((dstWidth + 1), &scaleScanline);
	if (returnCode != MEMORY_OK) {
		freeUnsignedCharArray(&xVector);
		freeDoubleArray(&yVector);
		freeDoubleArray(&scanline);
		return returnCode;
	}

	numRows = 0;
	nextRow = 1;
	ySpan = 1.0;
	yScale = factor;
	i = 0;

	for (y = 0; y < dstHeight; y++) {
		ty = y * dstWidth;

		memset(yVector, 0, srcWidth * sizeof(double));
		memset(scaleScanline, 0, dstWidth * sizeof(double));

		/* Scale Y-dimension. */
		while (yScale < ySpan) {
			if (nextRow && numRows < srcHeight) {
				/* Read a new scanline.  */
				memcpy(xVector, src, srcWidth);
				src += srcWidth;
				numRows++;
			}
			for (x = 0; x < srcWidth; x++) {
				yVector[x] += yScale * (double) xVector[x];
			}
			ySpan -= yScale;
			yScale = factor;
			nextRow = 1;
		}
		if (nextRow && numRows < srcHeight) {
			/* Read a new scanline.  */
			memcpy(xVector, src, srcWidth);
			src += srcWidth;
			numRows++;
			nextRow = 0;
		}
		s = scanline;
		for (x = 0; x < srcWidth; x++) {
			yVector[x] += ySpan * (double) xVector[x];
			*s = yVector[x];
			s++;
		}
		yScale -= ySpan;
		if (yScale <= 0) {
			yScale = factor;
			nextRow = 1;
		}
		ySpan = 1.0;

		nextCol = 0;
		xSpan = 1.0;
		s = scanline;
		t = scaleScanline;

		/* Scale X dimension. */
		for (x = 0; x < srcWidth; x++) {
			xScale = factor;
			while (xScale >= xSpan) {
				if (nextCol) {
					t++;
				}
				t[0] += xSpan * s[0];
				xScale -= xSpan;
				xSpan = 1.0;
				nextCol = 1;
			}
			if (xScale > 0) {
				if (nextCol) {
					nextCol = 0;
					t++;
				}
				t[0] += xScale * s[0];
				xSpan -= xScale;
			}
			s++;
		}

		/* Copy scanline to target. */
		t = scaleScanline;
		for (x = 0; x < dstWidth; x++) {
			dst[ty + x] = (unsigned char) t[x];
		}
	}

	freeUnsignedCharArray(&xVector);
	freeDoubleArray(&yVector);
	freeDoubleArray(&scanline);
	freeDoubleArray(&scaleScanline);

	return MEMORY_OK;
}
Exemplo n.º 11
0
int decodeResizeImage(char const *filename, int maxPixels, Bitmap* bitmap) {
    LOGI("decodeResizeImage. START");
    int returnCode;

    int maxWidth;
    int maxHeight;

    // Decode Image
    returnCode = decodeImage(filename, bitmap);

    if (returnCode != MEMORY_OK) {
        LOGE("Failed to decode image");
        freeUnsignedCharArray(&(*bitmap).red);
        freeUnsignedCharArray(&(*bitmap).green);
        freeUnsignedCharArray(&(*bitmap).blue);
        return returnCode;
    }
    LOGI("decodeResizeImage. IMAGE DECODED");

    doTransforms(bitmap, 1, 0, 0);
    // Resize red channel
    getScaledSize((*bitmap).redWidth, (*bitmap).redHeight, maxPixels, &maxWidth, &maxHeight); //We only need to do this once as r, g, b should be the same sizes
    returnCode = resizeChannel(&(*bitmap).red, (*bitmap).redWidth, (*bitmap).redHeight, maxWidth, maxHeight);
    if (returnCode != MEMORY_OK) {
        freeUnsignedCharArray(&(*bitmap).red);
        return returnCode;
    }
    // Set red channel dimensions
    if ((*bitmap).redWidth >= maxWidth && (*bitmap).redHeight >= maxHeight) {
        (*bitmap).redWidth = maxWidth;
        (*bitmap).redHeight = maxHeight;
    }
    LOGI("decodeResizeImage. RED COMPLETE");

    /**
     * GREEN CHANNEL
     */
    doTransforms(bitmap, 0, 1, 0);
    // Resize green channel
    returnCode = resizeChannel(&(*bitmap).green, (*bitmap).greenWidth, (*bitmap).greenHeight, maxWidth, maxHeight);
    if (returnCode != MEMORY_OK) {
        freeUnsignedCharArray(&(*bitmap).red);
        freeUnsignedCharArray(&(*bitmap).green);
        return returnCode;
    }
    // Set green channel dimensions
    if ((*bitmap).greenWidth >= maxWidth && (*bitmap).greenHeight >= maxHeight) {
        (*bitmap).greenWidth = maxWidth;
        (*bitmap).greenHeight = maxHeight;
    }
    LOGI("decodeResizeImage. GREEN COMPLETE");


    /**
     * BLUE CHANNEL
     */
    doTransforms(bitmap, 0, 0, 1);
    // Resize blue channel
    returnCode = resizeChannel(&(*bitmap).blue, (*bitmap).blueWidth, (*bitmap).blueHeight, maxWidth, maxHeight);
    if (returnCode != MEMORY_OK) {
        freeUnsignedCharArray(&(*bitmap).red);
        freeUnsignedCharArray(&(*bitmap).green);
        freeUnsignedCharArray(&(*bitmap).blue);
        return returnCode;
    }
    // Set blue channel dimensions
    if ((*bitmap).blueWidth >= maxWidth && (*bitmap).blueHeight >= maxHeight) {
        (*bitmap).blueWidth = maxWidth;
        (*bitmap).blueHeight = maxHeight;
    }
    LOGI("decodeResizeImage. BLUE COMPLETE");


    // Set the final bitmap dimensions
    if ((*bitmap).redWidth == (*bitmap).greenWidth && (*bitmap).redWidth == (*bitmap).blueWidth
            && (*bitmap).redHeight == (*bitmap).greenHeight && (*bitmap).redHeight == (*bitmap).blueHeight) {
        (*bitmap).width = (*bitmap).redWidth;
        (*bitmap).height = (*bitmap).redHeight;
    } else {
        freeUnsignedCharArray(&(*bitmap).red);
        freeUnsignedCharArray(&(*bitmap).green);
        freeUnsignedCharArray(&(*bitmap).blue);
        return INCONSISTENT_BITMAP_ERROR;
    }
    LOGI("decodeResizeImage. FINISHED");

    return MEMORY_OK;
}