Even without any exposure to the C language, I was able to develop an HTTP server with various functionalities solely relying on AI tools and my own ideas. Throughout the process, I didn't consult any manuals or use Google. I completed it within just a couple of days during my free time. Of course, after accomplishing the first project, I gained the ability to comprehend code and write some C code manually.
Now, I plan to implement my own graphics processing library in C. Each graphic has its own concept in the form of a struct, along with related operations. Floating-point numbers are used for conceptual calculations, and the conversion to integer points is only done when necessary for rendering images. These concepts and parameters can be separated and saved or processed in other forms. The ultimate goal is to have complete control over every detail of the entire process and develop higher-level functionalities.
From refining the concept to implementation and validating my ideas, I have already completed most of the basic elements and implemented many operation methods. The most important aspect of this process is to persist with the concept and employ methods to test the correctness of the generated code. Code generated by AI must not be used directly; it must pass testing before being integrated into existing code. Incorrectly outputted code has no value. Language syntax is not a significant issue, and after adapting to such strict syntax, the chances of errors actually decrease. This is just the basic framework, and there are still many features to be added. We are currently testing and adding them gradually. Especially when the code becomes more complex, it's not advisable to simply copy and paste large chunks of code for AI processing, as it may not produce the desired results and even cause issues with the previously functional code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cassert>
#include <assert.h>
#include <vector>
#include <cmath>
#include <stdint.h>
#include <iostream>
struct Color {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
struct Point2D {
float x;
float y;
};
struct Matrix {
int width;
int height;
unsigned char* array;
Matrix(int w, int h,unsigned char value=0) {
width = w;
height = h;
array = (unsigned char*)malloc(width * height * sizeof(unsigned char));
if (array == NULL) {
fprintf(stderr, "Failed to allocate memory for array\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < width * height; i++) {
array[i] = value ;
}
}
~Matrix() {
free(array);
}
int getWidth() {
return width;
}
int getHeight() {
return height;
}
unsigned char getValue(Point2D point) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return 0;
}
return array[y * width + x];
}
void setValue(Point2D point, unsigned char value) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return;
}
array[y * width + x] = value;
}
Matrix resize(int newWidth, int newHeight) {
Matrix resizedMatrix(newWidth, newHeight);
float xRatio = (float)width / newWidth;
float yRatio = (float)height / newHeight;
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++) {
float srcX = x * xRatio;
float srcY = y * yRatio;
Point2D srcPoint = { srcX, srcY };
unsigned char value = getValue(srcPoint);
Point2D destPoint = { (float)x, (float)y };
resizedMatrix.setValue(destPoint, value);
}
}
return resizedMatrix;
}
Matrix crop(int startX, int startY, int endX, int endY) {
Matrix croppedMatrix(endX - startX, endY - startY);
for (int y = startY; y < endY; y++) {
for (int x = startX; x < endX; x++) {
Point2D srcPoint = { (float)x, (float)y };
unsigned char value = getValue(srcPoint);
Point2D destPoint = { (float)(x - startX), (float)(y - startY) };
croppedMatrix.setValue(destPoint, value);
}
}
return croppedMatrix;
}
void printMatrix() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Point2D point = { (float)x, (float)y };
unsigned char value = getValue(point);
printf("%2u", value);
}
printf("\n");
}
}
void printArray() {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Point2D point = { (float)x, (float)y };
unsigned char value = getValue(point);
printf("%1u", value);
}
}
printf("\n");
}
};
struct Image {
private:
int width;
int height;
Color* array;
int getIndex(int x, int y) {
return y * width + x;
}
public:
Image(int w, int h,Color color={0,0,0,255}) {
width = w;
height = h;
array = (Color*)malloc(width * height * sizeof(Color));
if (array == NULL) {
fprintf(stderr, "Failed to allocate memory for array\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < width * height; i++) {
array[i]=color;
}
}
~Image() {
free(array);
}
int getWidth() {
return width;
}
int getHeight() {
return height;
}
unsigned int getPointChannel(Point2D point, char channel) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return 0;
}
Color color = array[getIndex(x, y)];
switch (channel) {
case 'r':
return color.r;
case 'g':
return color.g;
case 'b':
return color.b;
case 'a':
return color.a;
default:
return 0;
}
}
void setPointChannel(Point2D point, char channel, int value) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return ;
}
Color color = array[getIndex(x, y)];
switch (channel) {
case 'r':
color.r = (unsigned char)value;
break;
case 'g':
color.g = (unsigned char)value;
break;
case 'b':
color.b = (unsigned char)value;
break;
case 'a':
color.a = (unsigned char)value;
break;
default:
return;
}
array[getIndex(x, y)] = color;
}
Color getPoint(Point2D point) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return {0, 0, 0, 0};
}
return array[getIndex(x, y)];
}
void setPoint(Point2D point, Color color) {
int x = round(point.x);
int y = round(point.y);
if (x < 0 || x >= width || y < 0 || y >= height) {
return;
}
array[getIndex(x, y)] = color;
}
Matrix getMatrix(char channel) {
Matrix matrix(width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Point2D point = { (float)x, (float)y };
unsigned char value = 0;
switch (channel) {
case 'r':
value = array[getIndex(x, y)].r;
break;
case 'g':
value = array[getIndex(x, y)].g;
break;
case 'b':
value = array[getIndex(x, y)].b;
break;
case 'a':
value = array[getIndex(x, y)].a;
break;
default:
value = 0;
}
matrix.setValue(point, value);
}
}
return matrix;
}
void setMatrix(char channel, Matrix matrix) {
if (width != matrix.getWidth() || height != matrix.getHeight()) {
fprintf(stderr, "Matrix dimensions do not match\n");
return;
}
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Point2D point = { (float)x, (float)y };
unsigned char value = matrix.getValue(point);
switch (channel) {
case 'r':
array[getIndex(x, y)].r = value;
break;
case 'g':
array[getIndex(x, y)].g = value;
break;
case 'b':
array[getIndex(x, y)].b = value;
break;
case 'a':
array[getIndex(x, y)].a = value;
break;
default:
return;
}
}
}
}
Image resize(int newWidth, int newHeight) {
Image resizedImage(newWidth, newHeight);
float xRatio = (float)width / newWidth;
float yRatio = (float)height / newHeight;
for (int y = 0; y < newHeight; y++) {
for (int x = 0; x < newWidth; x++) {
float srcX = x * xRatio;
float srcY = y * yRatio;
Point2D srcPoint = { srcX, srcY };
Color color = getPoint(srcPoint);
Point2D destPoint = { (float)x, (float)y };
resizedImage.setPoint(destPoint, color);
}
}
return resizedImage;
}
Image crop(int startX, int startY, int endX, int endY) {
Image croppedImage(endX - startX, endY - startY);
for (int y = startY; y < endY; y++) {
for (int x = startX; x < endX; x++) {
Point2D srcPoint = { (float)x, (float)y };
Color color = getPoint(srcPoint);
Point2D destPoint = { (float)(x - startX), (float)(y - startY) };
croppedImage.setPoint(destPoint, color);
}
}
return croppedImage;
}
};
struct StraightLine {
Point2D p0;
Point2D p1;
std::vector<Point2D> toPoints() {
std::vector<Point2D> points;
int dx = p1.x - p0.x;
int dy = p1.y - p0.y;
int absDx = std::abs(dx);
int absDy = std::abs(dy);
int steps = std::max(absDx, absDy);
float incX = static_cast<float>(dx) / steps;
float incY = static_cast<float>(dy) / steps;
float currentX = p0.x;
float currentY = p0.y;
for (int i = 0; i < steps; i++) {
Point2D point;
point.x = currentX;
point.y = currentY;
points.push_back(point);
currentX += incX;
currentY += incY;
}
Point2D point;
point.x = p1.x;
point.y = p1.y;
points.push_back(point);
return points;
}
};
struct Bezier {
Point2D* points;
Point2D controlPoint;
std::vector<Point2D> toPoints() {
std::vector<Point2D> curvePoints;
for (int t = 0; t <= 100; t++) {
float u = t / 100.0;
float x = 0.0, y = 0.0;
Point2D* p = points;
while (p < points + 3) {
x += p->x * binomialCoefficient(2, p - points) * pow(u, p - points) * pow(1 - u, 2 - (p - points));
y += p->y * binomialCoefficient(2, p - points) * pow(u, p - points) * pow(1 - u, 2 - (p - points));
p++;
}
curvePoints.push_back({ round(x), round(y) });
if (t < 100 && curvePoints[curvePoints.size() - 1].x == curvePoints[curvePoints.size() - 2].x && curvePoints[curvePoints.size() - 1].y == curvePoints[curvePoints.size() - 2].y) {
curvePoints.pop_back();
}
}
return curvePoints;
}
int binomialCoefficient(int n, int k) {
if (k == 0 || k == n)
return 1;
int numerator = 1, denominator = 1;
for (int i = 1; i <= k; i++) {
denominator *= i;
numerator *= (n - i + 1);
}
return numerator / denominator;
}
};
struct Rectangle
{
Point2D topLeft;
Point2D bottomRight;
struct Polygon toPolygon();
};
struct Circle
{
Point2D center;
float radius;
};
struct Ellipse
{
Point2D center;
float xRadius;
float yRadius;
};
struct Polygon
{
int N;
Point2D *points;
struct StraightLine *scanLineX(int startY, int endY);
struct StraightLine *scanLineY(int startX, int endX);
};
struct Curve
{
int N;
Point2D *points;
};
struct Line
{
int N;
Point2D *points;
Point2D *toPoints(int numberOfPoints);
};
StraightLine *Polygon::scanLineX(int startY, int endY)
{
StraightLine *lines = new StraightLine[abs(endY - startY) + 1];
for (int y = startY; y <= endY; y++)
{
std::vector<float> intersections;
for (int i = 0; i < N; i++)
{
int j = (i + 1) % N;
if ((points[i].y <= y && points[j].y > y) || (points[i].y > y && points[j].y <= y))
{
float t = (y - points[i].y) / (points[j].y - points[i].y);
float x = points[i].x + t * (points[j].x - points[i].x);
intersections.push_back(x);
}
}
if (intersections.size() >= 2)
{
StraightLine line;
line.p0.x = intersections[0];
line.p0.y = y;
line.p1.x = intersections[1];
line.p1.y = y;
lines[y - startY] = line;
}
}
return lines;
}
StraightLine *Polygon::scanLineY(int startX, int endX)
{
StraightLine *lines = new StraightLine[abs(endX - startX) + 1];
for (int x = startX; x <= endX; x++)
{
std::vector<float> intersections;
for (int i = 0; i < N; i++)
{
int j = (i + 1) % N;
if ((points[i].x <= x && points[j].x > x) || (points[i].x > x && points[j].x <= x))
{
float t = (x - points[i].x) / (points[j].x - points[i].x);
float y = points[i].y + t * (points[j].y - points[i].y);
intersections.push_back(y);
}
}
if (intersections.size() >= 2)
{
StraightLine line;
line.p0.x = x;
line.p0.y = intersections[0];
line.p1.x = x;
line.p1.y = intersections[1];
lines[x - startX] = line;
}
}
return lines;
}
struct Polygon Rectangle::toPolygon()
{
struct Polygon polygon;
polygon.N = 4;
polygon.points = (Point2D *)malloc(polygon.N * sizeof(Point2D));
polygon.points[0].x = topLeft.x;
polygon.points[0].y = topLeft.y;
polygon.points[1].x = bottomRight.x;
polygon.points[1].y = topLeft.y;
polygon.points[2].x = bottomRight.x;
polygon.points[2].y = bottomRight.y;
polygon.points[3].x = topLeft.x;
polygon.points[3].y = bottomRight.y;
return polygon;
}
int main() {
// Test Image
Image image(10, 10);
// Get and set a point outside the image range
Point2D point = {1, 9};
Color pointColor = image.getPoint(point);
printf("Point color: %u, %u, %u, %u\n", pointColor.r, pointColor.g, pointColor.b, pointColor.a);
point = {5, 5};
image.setPoint(point, { 111, 222, 0, 128 });
// Get and set a point within the image range
Color color = image.getPoint(point);
printf("Point color: %u, %u, %u, %u\n", color.r, color.g, color.b, color.a);
// Get and set a point channel within the image range
int channelValue = image.getPointChannel(point, 'r');
printf("Point channel value: %d\n", channelValue);
image.setPointChannel(point, 'r', 128);
channelValue = image.getPointChannel(point, 'r');
printf("Point channel value: %d\n", channelValue);
Matrix m=Matrix(10,10,1);
m.setValue({5,5},9);
m.printMatrix();
m.printArray();
Matrix m1=m.crop(0,0,6,6);
m1.printMatrix();
Matrix m2=m.resize(19,19);
m2.printMatrix();
m2.printArray();
printf("Image img=Image(20,20,{1,2,3,4});\n");
Image img=Image(20,20,{1,2,3,4});
printf("Matrix R\n");
Matrix R=img.getMatrix('r');
R.printMatrix();
printf("Matrix G\n");
Matrix G=img.getMatrix('g');
G.printMatrix();
printf("Matrix B\n");
Matrix B=img.getMatrix('b');
B.printMatrix();
printf("Matrix A\n");
Matrix A=img.getMatrix('a');
A.printMatrix();
struct Rectangle rect;
rect.topLeft.x = 0;
rect.topLeft.y = 0;
rect.bottomRight.x = 10;
rect.bottomRight.y = 10;
struct Polygon poly = rect.toPolygon();
struct StraightLine *xLines= poly.scanLineX(0,10);
for (int i = 0; i <=10; i++)
{
printf("scanLineX %d: (%.0f, %.0f) to (%.0f, %.0f)\n", i , xLines[i].p0.x, xLines[i].p0.y, xLines[i].p1.x, xLines[i].p1.y);
}
struct StraightLine *yLines = poly.scanLineY(0, 10);
for (int i = 0; i <= 10; i++)
{
printf("scanLineY %d: (%.0f, %.0f) to (%.0f, %.0f)\n", i , yLines[i].p0.x, yLines[i].p0.y, yLines[i].p1.x, yLines[i].p1.y);
}
printf("line.toPoints\n");
StraightLine line = {{0, 0}, {9, 9}};
std::vector<Point2D> points = line.toPoints();
for (auto point : points) {
printf("(%.0f, %.0f)\n", point.x, point.y);
}
Bezier curve;
printf("Bezier curve.toPoints\n");
// Set control point
curve.controlPoint = { 1, 2 };
// Set curve points
curve.points = new Point2D[3];
curve.points[0] = { 0, 0 };
curve.points[1] = { 5, 5 };
curve.points[2] = { 8, 6 };
// Get curve points
std::vector<Point2D> points2 = curve.toPoints();
// Print curve points
for (Point2D& point : points2) {
printf("(%.0f, %.0f)\n", point.x, point.y);
}
return 0;
}
Added functionality to load images and save them as pictures. The pixel data of the PNG and JPEG images are inputted into a one-dimensional array. After a series of operations, the modified image is saved as a new file to verify if the basic functions are working correctly.
沒有留言:
發佈留言