Blame view

libs/JpegUtils/pyjpeg/jpeg.c 3.2 KB
84648488   Chunk   reverted.
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
#include "jpeg.h"
#include <stdio.h>

char writejpeg(FILE *outfile, struct jpeg_stuff *src) {
  struct jpeg_decompress_struct *injpeg = &src->cinfo;
  jvirt_barray_ptr *src_coeffs = src->src_coeffs;
  
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_compress(&cinfo);

  jpeg_copy_critical_parameters(injpeg, &cinfo);
  if (jerr.num_warnings != 0) {
    return -1;
  }
  cinfo.optimize_coding = TRUE;
  jpeg_stdio_dest(&cinfo, outfile);
  if (jerr.num_warnings != 0) {
    return -1;
  }
  jpeg_write_coefficients(&cinfo, src_coeffs);
  if (jerr.num_warnings != 0) {
    return -1;
  }
  jpeg_finish_compress(&cinfo);
  if (jerr.num_warnings != 0) {
    return -1;
  }
  return 0;
}

char readjpeg(FILE *infile, struct jpeg_stuff *dest) {
  struct jpeg_decompress_struct *cinfo = &dest->cinfo;
  cinfo->err = jpeg_std_error(&dest->jerr);
  jpeg_create_decompress(cinfo);
  jpeg_stdio_src(cinfo, infile);
  if (cinfo->err->num_warnings != 0) {
    return -1;
  }
  char magic[2];
  size_t len = fread(&magic, 1, 2, infile);
  if (len != (size_t) 2 || magic[0] != (char)0xff || magic[1] != (char)0xd8) {
    return -1;
  }
  fseek(infile, 0, SEEK_SET);
  int header_status = jpeg_read_header(cinfo, FALSE);
  if (header_status != JPEG_HEADER_OK || cinfo->err->num_warnings != 0) {
    return -1;
  }
  jpeg_core_output_dimensions(cinfo);
  if (cinfo->err->num_warnings != 0) {
    return -1;
  }

  jvirt_barray_ptr *coeffs = jpeg_read_coefficients(cinfo);
  if (cinfo->err->num_warnings != 0) {
    return -1;
  }
  dest->src_coeffs = coeffs;

  return 0;

}
void closejpeg(struct jpeg_stuff *src) {
  jpeg_finish_decompress(&src->cinfo);
  jpeg_destroy_decompress(&src->cinfo);
  // should dispose of associated block arrays
}

char check_block_coords(struct jpeg_stuff *stuff, int x, int y, int comp) {
  struct jpeg_decompress_struct *cinfo = &stuff->cinfo;
  if (comp < 0 || comp > cinfo->num_components) {
    return -1;
  }
  jpeg_component_info *ji = cinfo->comp_info + comp;
  if (y < 0 || ((unsigned int) y) >= ji->height_in_blocks) {
    return -1;
  }
  if (x < 0 || ((unsigned int) x) >= ji->width_in_blocks) {
    return -1;
  }
  return 0;
}

JBLOCKARRAY get_coeff_barray_rows_internal(struct jpeg_stuff *stuff, int y, int comp, unsigned int rowcount) {
  struct jpeg_decompress_struct *cinfo = &stuff->cinfo;
  return cinfo->mem->access_virt_barray((j_common_ptr)cinfo,
      stuff->src_coeffs[comp], y, rowcount, TRUE);
}

JBLOCKARRAY get_coeff_barray_rows(struct jpeg_stuff *stuff, int y, int comp, unsigned int rowcount) {
  if (check_block_coords(stuff, 0, y, comp) != 0) {
    return NULL;
  }
  if (y + rowcount > stuff->cinfo.comp_info[comp].height_in_blocks) {
    return NULL;
  }
  return get_coeff_barray_rows_internal(stuff, y, comp, rowcount);
}

JCOEFPTR get_coeff_block(struct jpeg_stuff *stuff, int x, int y, int comp) {
  if (check_block_coords(stuff, x, y, comp) != 0) {
    return NULL;
  }
  jpeg_component_info *ji = stuff->cinfo.comp_info + comp;
  int rowindex = y % ji->v_samp_factor;
  int row = y - rowindex;
  JBLOCKARRAY jb = get_coeff_barray_rows_internal(stuff, row, comp, ji->v_samp_factor);
  if (jb == NULL) {
    return NULL;
  }
  return jb[rowindex][x];
}