Skip to content

Commit

Permalink
split c files
Browse files Browse the repository at this point in the history
  • Loading branch information
victorvde committed Jun 3, 2015
1 parent 906f418 commit 901a247
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 138 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,10 @@ CFLAGS:=-std=c11 -Wall -Wextra -Winline -pedantic -Ofast -march=pentium4 -s -DND
#CFLAGS:=-std=c11 -Wall -Wextra -pedantic -Og -g
LIBS:=-ljpeg -lpng -lfftw3f -lm

jpeg2png: jpeg2png.c
$(CC) $< -o $@ $(CFLAGS) $(LIBS)
SRCS:=jpeg2png.c utils.c jpeg.c

jpeg2png: jpeg2png.o utils.o jpeg.o png.o
$(CC) $^ -o $@ $(LIBS)

%o: %.c *.h
$(CC) $< -o $@ $(CFLAGS)
49 changes: 49 additions & 0 deletions jpeg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#include <jpeglib.h>

#include "jpeg.h"
#include "utils.h"

void read_jpeg(FILE *in, struct jpeg *jpeg) {
struct jpeg_decompress_struct d;
struct jpeg_error_mgr jerr;
d.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&d);
jpeg_stdio_src(&d, in);
jpeg_read_header(&d, true);

jpeg->h = d.image_height;
jpeg->w = d.image_width;

if(d.num_components != 3) { die("only 3 component jpegs are supported"); }

for(int c = 0; c < d.num_components; c++) {
int i = d.comp_info[c].quant_tbl_no;
JQUANT_TBL *t = d.quant_tbl_ptrs[i];
memcpy(jpeg->quant_table[c], t->quantval, sizeof(uint16_t) * 64);
}

jvirt_barray_ptr *coefs = jpeg_read_coefficients(&d);
for(int c = 0; c < d.num_components; c++) {
jpeg_component_info *i = &d.comp_info[c];
int h = i->height_in_blocks * 8;
int w = i->width_in_blocks * 8;
int16_t *data = malloc(w * h * sizeof(int16_t));
jpeg->coefs[c].w = w;
jpeg->coefs[c].h = h;
jpeg->coefs[c].data = data;
if(!data) { die("could not allocate memory for coefs"); }
for(int y = 0; y < h / 8; y++) {
JBLOCKARRAY b = d.mem->access_virt_barray((void*)&d, coefs[c], y, 1, false);
for(int x = 0; x < w / 8; x++) {
memcpy(data, b[0][x], 64 * sizeof(int16_t));
data += 64;
}
}
}
jpeg_destroy_decompress(&d);
}
16 changes: 16 additions & 0 deletions jpeg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef JPEG2PNG_JPEG_H
#define JPEG2PNG_JPEG_H

#include <stdio.h>

#include "jpeg2png.h"

struct jpeg {
int h;
int w;
uint16_t quant_table[3][64];
struct coef coefs[3];
};

void read_jpeg(FILE *in, struct jpeg *jpeg);
#endif
140 changes: 4 additions & 136 deletions jpeg2png.c
Original file line number Diff line number Diff line change
@@ -1,135 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include <assert.h>
#include <time.h>

#include <jpeglib.h>
#include <png.h>

#include <fftw3.h>

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define DUMP(v, f) do { printf( #v " = " f "\n", v); } while(false)

static noreturn void die(const char *msg, ...) {
if(msg) {
fprintf(stderr, "jpeg2png: ");
va_list l;
va_start(l, msg);
vfprintf(stderr, msg, l);
va_end(l);
fprintf(stderr, "\n");
} else {
perror("jpeg2png");
}
exit(EXIT_FAILURE);
}

struct coef {
int h;
int w;
int16_t *data;
float *fdata;
};

struct jpeg {
int h;
int w;
uint16_t quant_table[3][64];
struct coef coefs[3];
};

static void read_jpeg(FILE *in, struct jpeg *jpeg) {
struct jpeg_decompress_struct d;
struct jpeg_error_mgr jerr;
d.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&d);
jpeg_stdio_src(&d, in);
jpeg_read_header(&d, true);

jpeg->h = d.image_height;
jpeg->w = d.image_width;

if(d.num_components != 3) { die("only 3 component jpegs are supported"); }

for(int c = 0; c < d.num_components; c++) {
int i = d.comp_info[c].quant_tbl_no;
JQUANT_TBL *t = d.quant_tbl_ptrs[i];
memcpy(jpeg->quant_table[c], t->quantval, sizeof(uint16_t) * 64);
}

jvirt_barray_ptr *coefs = jpeg_read_coefficients(&d);
for(int c = 0; c < d.num_components; c++) {
jpeg_component_info *i = &d.comp_info[c];
int h = i->height_in_blocks * 8;
int w = i->width_in_blocks * 8;
int16_t *data = malloc(w * h * sizeof(int16_t));
jpeg->coefs[c].w = w;
jpeg->coefs[c].h = h;
jpeg->coefs[c].data = data;
if(!data) { die("could not allocate memory for coefs"); }
for(int y = 0; y < h / 8; y++) {
JBLOCKARRAY b = d.mem->access_virt_barray((void*)&d, coefs[c], y, 1, false);
for(int x = 0; x < w / 8; x++) {
memcpy(data, b[0][x], 64 * sizeof(int16_t));
data += 64;
}
}
}
jpeg_destroy_decompress(&d);
}

static float clamp(float x) {
return CLAMP(x, 0., 255.);
}

static void write_png(FILE *out, int w, int h, struct coef *y, struct coef *cb, struct coef *cr) {
png_struct *png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) { die("could not initialize PNG write struct"); }
png_info *info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) { die("could not initialize PNG info struct"); }
if (setjmp(png_jmpbuf(png_ptr)))
{
/* If we get here, we had a problem writing the file */
die("problem while writing PNG file");
}
png_init_io(png_ptr, out);
png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
png_byte *image_data = calloc(sizeof(png_byte), h * w * 3);
if(!image_data) { die("could not allocate image data");}

for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) {
int yi = y->fdata[i * y->w + j];
int cbi = cb->fdata[i * cb->w + j];
int cri = cr->fdata[i * cr->w + j];

image_data[(i*w+j)*3] = clamp(yi + 1.402 * cri);
image_data[(i*w+j)*3+1] = clamp(yi - 0.34414 * cbi - 0.71414 * cri);
image_data[(i*w+j)*3+2] = clamp(yi + 1.772 * cbi);
}
}

png_byte **rows = malloc(sizeof(*rows) * h);
if(!rows) { die("allocation failure"); }
for(int i = 0; i < h; i++) {
rows[i] = &image_data[i * w * 3];
}
png_write_image(png_ptr, rows);
free(rows);
png_write_end(png_ptr, info_ptr);
free(image_data);
png_destroy_write_struct(&png_ptr, &info_ptr);
}
#include "jpeg2png.h"
#include "utils.h"
#include "jpeg.h"
#include "png.h"

static void element_product(const int16_t data[64], const uint16_t quant_table[64], float *out) {
for(int i = 0; i < 64; i++) {
Expand Down Expand Up @@ -189,19 +70,6 @@ static void box(float *restrict in, float *restrict out, int w, int h) {
}
}

#define START_TIMER(n) clock_t macro_timer_##n = start_timer(#n);
static clock_t start_timer(const char *name) {
(void) name;
return clock();
}

#define STOP_TIMER(n) stop_timer(macro_timer_##n, #n);
static void stop_timer(clock_t t, const char *n) {
clock_t diff = clock() - t;
int msec = diff * 1000 / CLOCKS_PER_SEC;
printf("%s: %d ms\n", n, msec);
}

void decode_coefficients(struct coef *coef, uint16_t *quant_table) {
coef->fdata = fftwf_alloc_real(coef->h * coef->w);
if(!coef->fdata) { die("allocation error"); }
Expand Down
13 changes: 13 additions & 0 deletions jpeg2png.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef JPEG2PNG_JPEG2PNG_H
#define JPEG2PNG_JPEG2PNG_H

#include <stdint.h>

struct coef {
int h;
int w;
int16_t *data;
float *fdata;
};

#endif
50 changes: 50 additions & 0 deletions png.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <png.h>

#include "png.h"
#include "utils.h"

static float clamp(float x) {
return CLAMP(x, 0., 255.);
}

void write_png(FILE *out, int w, int h, struct coef *y, struct coef *cb, struct coef *cr) {
png_struct *png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr) { die("could not initialize PNG write struct"); }
png_info *info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) { die("could not initialize PNG info struct"); }
if (setjmp(png_jmpbuf(png_ptr)))
{
/* If we get here, we had a problem writing the file */
die("problem while writing PNG file");
}
png_init_io(png_ptr, out);
png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
png_byte *image_data = calloc(sizeof(png_byte), h * w * 3);
if(!image_data) { die("could not allocate image data");}

for(int i = 0; i < h; i++) {
for(int j = 0; j < w; j++) {
int yi = y->fdata[i * y->w + j];
int cbi = cb->fdata[i * cb->w + j];
int cri = cr->fdata[i * cr->w + j];

image_data[(i*w+j)*3] = clamp(yi + 1.402 * cri);
image_data[(i*w+j)*3+1] = clamp(yi - 0.34414 * cbi - 0.71414 * cri);
image_data[(i*w+j)*3+2] = clamp(yi + 1.772 * cbi);
}
}

png_byte **rows = malloc(sizeof(*rows) * h);
if(!rows) { die("allocation failure"); }
for(int i = 0; i < h; i++) {
rows[i] = &image_data[i * w * 3];
}
png_write_image(png_ptr, rows);
free(rows);
png_write_end(png_ptr, info_ptr);
free(image_data);
png_destroy_write_struct(&png_ptr, &info_ptr);
}
9 changes: 9 additions & 0 deletions png.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef JPEG2PNG_PNG_H
#define JPEG2PNG_PNG_H

#include <stdio.h>
#include "jpeg2png.h"

void write_png(FILE *out, int w, int h, struct coef *y, struct coef *cb, struct coef *cr);

#endif
30 changes: 30 additions & 0 deletions utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include "utils.h"

noreturn void die(const char *msg, ...) {
if(msg) {
fprintf(stderr, "jpeg2png: ");
va_list l;
va_start(l, msg);
vfprintf(stderr, msg, l);
va_end(l);
fprintf(stderr, "\n");
} else {
perror("jpeg2png");
}
exit(EXIT_FAILURE);
}

clock_t start_timer(const char *name) {
(void) name;
return clock();
}

void stop_timer(clock_t t, const char *n) {
clock_t diff = clock() - t;
int msec = diff * 1000 / CLOCKS_PER_SEC;
printf("%s: %d ms\n", n, msec);
}
19 changes: 19 additions & 0 deletions utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef JPEG2PNG_UTILS_H
#define JPEG2PNG_UTILS_H

#include <stdnoreturn.h>
#include <time.h>

noreturn void die(const char *msg, ...);
clock_t start_timer(const char *name);
void stop_timer(clock_t t, const char *n);

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define DUMP(v, f) do { printf( #v " = " f "\n", v); } while(false)

#define START_TIMER(n) clock_t macro_timer_##n = start_timer(#n);
#define STOP_TIMER(n) stop_timer(macro_timer_##n, #n);

#endif

0 comments on commit 901a247

Please sign in to comment.