예제 #1
0
파일: bitmap.c 프로젝트: ljyao/CampusMoment
int initBitmapMemory(Bitmap* bitmap, int width, int height) {
	deleteBitmap(bitmap);

	(*bitmap).width = width;
	(*bitmap).height = height;

	(*bitmap).redWidth = width;
	(*bitmap).redHeight = height;

	(*bitmap).greenWidth = width;
	(*bitmap).greenHeight = height;

	(*bitmap).blueWidth = width;
	(*bitmap).blueHeight = height;

	int size = width*height;

	int resultCode = newUnsignedCharArray(size, &(*bitmap).red);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}

	resultCode = newUnsignedCharArray(size, &(*bitmap).green);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}

	resultCode = newUnsignedCharArray(size, &(*bitmap).blue);
	if (resultCode != MEMORY_OK) {
		return resultCode;
	}
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
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;
}
예제 #5
0
파일: bitmap.c 프로젝트: ljyao/CampusMoment
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;
}
예제 #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;
}
예제 #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;
}
예제 #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);
}
예제 #9
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;
}
예제 #10
0
파일: bitmap.c 프로젝트: hailongfeng/huiyin
int decodeImage(char const *filename, Bitmap* bitmap) {
    // Delete the current bitmap, just in case
    deleteBitmap(bitmap);

    int width, height, comp;
    unsigned char *data = stbi_load(filename, &width, &height, &comp, 0);
    LOGI("stbi_image Loaded Image. %dx%d, Components: %d. Size: %d", width, height, comp, sizeof(data));

    // Check for bad decode...
    if (!data || comp <= 2) {
        // Free Image
        stbi_image_free(data);
        return DECODE_ERROR;
    }

    int size = width * height;

    // Create Char Arrays to store pixel data
    unsigned char* red;
    unsigned char* green;
    unsigned char* blue;

    int resultCode = newUnsignedCharArray(size, &red);
    if (resultCode != MEMORY_OK) {
        return resultCode;
    }
    resultCode = newUnsignedCharArray(size, &green);
    if (resultCode != MEMORY_OK) {
        return resultCode;
    }
    resultCode = newUnsignedCharArray(size, &blue);
    if (resultCode != MEMORY_OK) {
        return resultCode;
    }

    // Split values into R, G, B
    int x, y;
    int index = 0;
    for (y = 0; y < height; y++)
    {
        for (x = 0; x < width; x++)
        {
            red[index] = data[index*comp];
            green[index] = data[(index*comp)+1];
            blue[index] = data[(index*comp)+2];
            index++;
        }
    }

    // Free Image
    stbi_image_free(data);

    (*bitmap).red = red;
    (*bitmap).green = green;
    (*bitmap).blue = blue;
    (*bitmap).redHeight = height;
    (*bitmap).redWidth = width;
    (*bitmap).greenHeight = height;
    (*bitmap).greenWidth = width;
    (*bitmap).blueHeight = height;
    (*bitmap).blueWidth = width;

    return MEMORY_OK;
}