These files are a partial wrapper of some functionality in libjpeg to make a python module.
Code samples on this website come without any guarantees – use them at your own risk! I am grateful for comments or patches sent to my email address: first name.last name@cl.cam.ac.uk.
from ctypes import cdll, Structure, c_char_p, pointer, POINTER, Array, cast, addressof, sizeof
from pylibjpegtypes import jpeg_info
class libjpeg:
def __init__(self):
pylibjpeg = cdll.LoadLibrary('pylibjpeg/pylibjpeg.so')
self.load_jpeg_file = pylibjpeg.load_jpeg_file
self.load_jpeg_file.restype = POINTER(jpeg_info)
self.load_jpeg_file.argtypes = [c_char_p,]
def get_jpeg_info(self, file_name):
info = self.load_jpeg_file(file_name)
component_count = info.contents.component_count
blocks = []
qmatrices = []
for ci in range(0, component_count):
bw = info.contents.width_blocks[ci]
bh = info.contents.height_blocks[ci]
this_component = []
for by in range(0, bh):
for bx in range(0, bw):
this_component.append(info.contents.dct_coefficients[ci][64 * (bx + by * bw) : 64 * (bx + by * bw) + 64])
blocks.append(this_component)
qmatrices.append(info.contents.quantization_tables[ci][0 : 64])
return (qmatrices, blocks)
#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <jerror.h>
#include <inttypes.h>
#include "ijgdct.h"
#define BLOCK_SIZE 64
typedef struct jpeg_info
{
uint8_t component_count;
uint16_t* width_blocks;
uint16_t* height_blocks;
uint16_t** quantization_tables;
int32_t** dct_coefficients;
} jpeg_info;
jpeg_info* load_jpeg_file(const char* file_name);
#include "pylibjpeg.h"
jpeg_info* load_jpeg_file(const char* file_name)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
jpeg_info* result;
jvirt_barray_ptr* coeff_arrays;
int ci, by, bx, bi;
FILE* infile;
// Create decompression object.
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
if ((infile = fopen(file_name, "rb")) == NULL)
{
fprintf(stderr, "Can't open %s\n", file_name);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
// Get all compression parameters.
jpeg_read_header(&cinfo, TRUE);
// Read coefficients.
coeff_arrays = jpeg_read_coefficients(&cinfo);
// Setup the result structure.
// TODO: Deal with component count != 3 case.
result = (jpeg_info*)malloc(sizeof(jpeg_info));
result->component_count = 3;
result->quantization_tables = (uint16_t**)malloc(sizeof(uint16_t*) * result->component_count);
result->dct_coefficients = (int32_t**)malloc(sizeof(int32_t*) * result->component_count);
result->width_blocks = (uint16_t*)malloc(sizeof(uint16_t) * result->component_count);
result->height_blocks = (uint16_t*)malloc(sizeof(uint16_t) * result->component_count);
for (ci = 0; ci < 3; ci++)
{
JBLOCKARRAY buffer;
JCOEFPTR blockptr;
jpeg_component_info* compptr;
compptr = cinfo.comp_info + ci;
result->quantization_tables[ci] = (uint16_t*)malloc(sizeof(uint16_t) * BLOCK_SIZE);
for (bi = 0; bi < BLOCK_SIZE; bi++)
result->quantization_tables[ci][bi] = compptr->quant_table->quantval[bi];
result->width_blocks[ci] = compptr->width_in_blocks;
result->height_blocks[ci] = compptr->height_in_blocks;
result->dct_coefficients[ci] = (int32_t*)malloc(sizeof(int32_t) * compptr->width_in_blocks * compptr->height_in_blocks * BLOCK_SIZE);
for (by = 0; by < compptr->height_in_blocks; by++)
{
buffer = (cinfo.mem->access_virt_barray)((j_common_ptr)&cinfo, coeff_arrays[ci], by, (JDIMENSION)1, FALSE);
for (bx = 0; bx < compptr->width_in_blocks; bx++)
{
blockptr = buffer[0][bx];
for (bi = 0; bi < BLOCK_SIZE; bi++)
result->dct_coefficients[ci][BLOCK_SIZE * (bx + by * compptr->width_in_blocks) + bi] = blockptr[bi];
//int clips = block_idct(block);
//if (clips & 1)
// printf("Clips at 255\n");
//if (clips & 2)
// printf("Clips at 0\n");
}
}
}
// Clean up.
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return result;
}
from ctypes import cdll, Structure, c_uint8, c_uint16, c_int32, c_char_p, pointer, POINTER
class jpeg_info(Structure):
_fields_ = [
('component_count', c_uint8),
('width_blocks', POINTER(c_uint16)),
('height_blocks', POINTER(c_uint16)),
('quantization_tables', POINTER(POINTER(c_uint16))),
('dct_coefficients', POINTER(POINTER(c_int32)))]
OBJ=pylibjpeg.o CC=gcc CFLAGS=-Wall -g3 -fPIC UNAME=$(shell uname) ifeq ($(UNAME), Darwin) SO_NAME=pylibjpeg.0.dylib SO_NAME_MINOR=pylibjpeg.0.0.dylib LINKER_FLAGS=-dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,0.0,-current_version,0.0,-install_name,$(SO_NAME) else SO_NAME=pylibjpeg.so.0 SO_NAME_MINOR=pylibjpeg.so.0.0 LINKER_FLAGS=-shared -Wl,-soname,$(SO_NAME) endif all: $(SO_NAME_MINOR) pylibjpeg.o: $(SO_NAME_MINOR): $(OBJ) gcc -Wall $(LINKER_FLAGS) -o $(SO_NAME_MINOR) $(OBJ) -ljpeg -lc -ln -f -s $(SO_NAME_MINOR) $(SO_NAME) clean: -rm $(SO_NAME_MINOR) -rm $(SO_NAME) -rm $(OBJ)