-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjpeg.cpp
More file actions
123 lines (84 loc) · 3.1 KB
/
jpeg.cpp
File metadata and controls
123 lines (84 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// jpeg.cpp
// jpeg
//
// Created by Blake Johnson on 10/15/19.
// Copyright © 2019 Blake Johnson. All rights reserved.
//
#include "jpeg.hpp"
#include "dct.hpp"
void Jpeg::generateJpeg(std::string img){
sourceImage = img;
srcImg.open(sourceImage); //for now no error checking will be conducted
parseDimensions();
parseColors();
divideIntoBlocks();
srcImg.close();
}
void Jpeg::parseDimensions(){
std::istringstream str;
std::string line = ""; //used to grab a line from the image
std::getline(srcImg, line); //grab the ppm type
std::getline(srcImg, line); //grab the dimensions line
str.str(line);
str >> width;
str >> height;
}
void Jpeg::parseColors(){
std::istringstream str;
std::string line = ""; //used to grab a line from the image
std::string token = ""; //used to grab elements from that line
std::getline(srcImg, line); //grab the color size
//initialize the colors 3 dimensional array: 3 channels x height x width
//Here could probably be the place to decide subsampling
colors = new double ** [3];
for(int i = 0; i < 3; i++){
colors[i] = new double * [height];
for( int j = 0; j<height; j++){
colors[i][j] = new double [width];
}
}
//now parse the image into the three channels. These will be rgb values from the file, so convert them to YCbCr
double rgb [3] = {0,0,0};
for(int i = 0; i < height; i++){
std::getline(srcImg, line);
str.str(line);
for(int j = 0; j < width; j++){
for (int k = 0; k < 3 ; k++){
str >> token;
rgb[k] = std::stoi(token);
}
rgbToYCbCr(rgb);
colors[0][i][j] = rgb[0];
colors[1][i][j] = rgb[1];
colors[2][i][j] = rgb[2];
}
}
}
void Jpeg::rgbToYCbCr(double YcBcR[]){
/*
|Y | |_ _ _| |r|
|Cr| = |_ _ _| * |g|
|Cr| |_ _ _| |b|
to convert rgb into YCbCr, use this matrix equation. credits to wikipedia, the equations with the "A" matrix values are already solved
*/
double r = YcBcR[0];
double g = YcBcR[1];
double b = YcBcR[2];
YcBcR[0] = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b);
YcBcR[1] = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b);
YcBcR[2] = 128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b);
}
void Jpeg::divideIntoBlocks(){
//This function, for now, assumes that the x and y diminsions of the ppm image are divisible by 8
//This means that a real amount of nxn blocks will be created and no block will need to be filled in with fake data
//Find offsets for every top left pixel in every n x n block
for(int channel = 0; channel < 3; channel++){
for(int i = 0; i < width; i += 8){
for(int j = 0; j < height; j += 8){
}
}
}
DCT obj;
obj.fdct(0, 0, 0, *this);
}