-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
345 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
// memdjpeg - A super simple example of how to decode a jpeg in memory | ||
// Kenneth Finnegan, 2012 | ||
// blog.thelifeofkenneth.com | ||
// | ||
// After installing jpeglib, compile with: | ||
// cc memdjpeg.c -ljpeg -o memdjpeg | ||
// | ||
// Run with: | ||
// ./memdjpeg filename.jpg | ||
// | ||
// Version Date Time By | ||
// ------- ---------- ----- --------- | ||
// 0.01 2012-07-09 11:18 Kenneth Finnegan | ||
// | ||
|
||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/stat.h> | ||
|
||
#include <jpeglib.h> | ||
|
||
|
||
int main (int argc, char *argv[]) { | ||
int rc, i, j; | ||
|
||
if (argc != 2) { | ||
fprintf(stderr, "USAGE: %s filename.jpg\n", argv[0]); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
// SSS EEEEEEE TTTTTTT U U PPPP | ||
// SS SS E T U U P PP | ||
// S E T U U P PP | ||
// SS E T U U P PP | ||
// SSS EEEE T U U PPPP | ||
// SS E T U U P | ||
// S E T U U P | ||
// SS SS E T U U P | ||
// SSS EEEEEEE T UUU P | ||
|
||
// Variables for the source jpg | ||
struct stat file_info; | ||
unsigned long jpg_size; | ||
unsigned char *jpg_buffer; | ||
|
||
// Variables for the decompressor itself | ||
struct jpeg_decompress_struct cinfo; | ||
struct jpeg_error_mgr jerr; | ||
|
||
// Variables for the output buffer, and how long each row is | ||
unsigned long bmp_size; | ||
unsigned char *bmp_buffer; | ||
int row_stride, width, height, pixel_size; | ||
|
||
|
||
// Load the jpeg data from a file into a memory buffer for | ||
// the purpose of this demonstration. | ||
// Normally, if it's a file, you'd use jpeg_stdio_src, but just | ||
// imagine that this was instead being downloaded from the Internet | ||
// or otherwise not coming from disk | ||
rc = stat(argv[1], &file_info); | ||
if (rc) { | ||
fprintf(stderr, "FAILED to stat source jpg\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
jpg_size = file_info.st_size; | ||
jpg_buffer = (unsigned char*) malloc(jpg_size + 100); | ||
|
||
int fd = open(argv[1], O_RDONLY); | ||
i = 0; | ||
while (i < jpg_size) { | ||
rc = read(fd, jpg_buffer + i, jpg_size - i); | ||
printf("Input: Read %d/%lu bytes\n", rc, jpg_size-i); | ||
i += rc; | ||
} | ||
close(fd); | ||
|
||
// SSS TTTTTTT A RRRR TTTTTTT | ||
// SS SS T A A R RR T | ||
// S T A A R RR T | ||
// SS T A A R RR T | ||
// SSS T AAAAAAA RRRR T | ||
// SS T A A R RR T | ||
// S T A A R R T | ||
// SS SS T A A R R T | ||
// SSS T A A R R T | ||
|
||
printf("Proc: Create Decompress struct\n"); | ||
// Allocate a new decompress struct, with the default error handler. | ||
// The default error handler will exit() on pretty much any issue, | ||
// so it's likely you'll want to replace it or supplement it with | ||
// your own. | ||
cinfo.err = jpeg_std_error(&jerr); | ||
jpeg_create_decompress(&cinfo); | ||
|
||
|
||
printf("Proc: Set memory buffer as source\n"); | ||
// Configure this decompressor to read its data from a memory | ||
// buffer starting at unsigned char *jpg_buffer, which is jpg_size | ||
// long, and which must contain a complete jpg already. | ||
// | ||
// If you need something fancier than this, you must write your | ||
// own data source manager, which shouldn't be too hard if you know | ||
// what it is you need it to do. See jpeg-8d/jdatasrc.c for the | ||
// implementation of the standard jpeg_mem_src and jpeg_stdio_src | ||
// managers as examples to work from. | ||
jpeg_mem_src(&cinfo, jpg_buffer, jpg_size); | ||
|
||
|
||
printf("Proc: Read the JPEG header\n"); | ||
// Have the decompressor scan the jpeg header. This won't populate | ||
// the cinfo struct output fields, but will indicate if the | ||
// jpeg is valid. | ||
rc = jpeg_read_header(&cinfo, TRUE); | ||
|
||
if (rc != 1) { | ||
fprintf(stderr, "File does not seem to be a normal JPEG\n"); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
printf("Proc: Initiate JPEG decompression\n"); | ||
// By calling jpeg_start_decompress, you populate cinfo | ||
// and can then allocate your output bitmap buffers for | ||
// each scanline. | ||
jpeg_start_decompress(&cinfo); | ||
|
||
width = cinfo.output_width; | ||
height = cinfo.output_height; | ||
pixel_size = cinfo.output_components; | ||
|
||
printf("Proc: Image is %d by %d with %d components\n", | ||
width, height, pixel_size); | ||
|
||
bmp_size = width * height * pixel_size; | ||
bmp_buffer = (unsigned char*) malloc(bmp_size); | ||
|
||
// The row_stride is the total number of bytes it takes to store an | ||
// entire scanline (row). | ||
row_stride = width * pixel_size; | ||
|
||
|
||
printf("Proc: Start reading scanlines\n"); | ||
// | ||
// Now that you have the decompressor entirely configured, it's time | ||
// to read out all of the scanlines of the jpeg. | ||
// | ||
// By default, scanlines will come out in RGBRGBRGB... order, | ||
// but this can be changed by setting cinfo.out_color_space | ||
// | ||
// jpeg_read_scanlines takes an array of buffers, one for each scanline. | ||
// Even if you give it a complete set of buffers for the whole image, | ||
// it will only ever decompress a few lines at a time. For best | ||
// performance, you should pass it an array with cinfo.rec_outbuf_height | ||
// scanline buffers. rec_outbuf_height is typically 1, 2, or 4, and | ||
// at the default high quality decompression setting is always 1. | ||
while (cinfo.output_scanline < cinfo.output_height) { | ||
unsigned char *buffer_array[1]; | ||
buffer_array[0] = bmp_buffer + \ | ||
(cinfo.output_scanline) * row_stride; | ||
|
||
jpeg_read_scanlines(&cinfo, buffer_array, 1); | ||
|
||
} | ||
printf("Proc: Done reading scanlines\n"); | ||
|
||
|
||
// Once done reading *all* scanlines, release all internal buffers, | ||
// etc by calling jpeg_finish_decompress. This lets you go back and | ||
// reuse the same cinfo object with the same settings, if you | ||
// want to decompress several jpegs in a row. | ||
// | ||
// If you didn't read all the scanlines, but want to stop early, | ||
// you instead need to call jpeg_abort_decompress(&cinfo) | ||
jpeg_finish_decompress(&cinfo); | ||
|
||
// At this point, optionally go back and either load a new jpg into | ||
// the jpg_buffer, or define a new jpeg_mem_src, and then start | ||
// another decompress operation. | ||
|
||
// Once you're really really done, destroy the object to free everything | ||
jpeg_destroy_decompress(&cinfo); | ||
// And free the input buffer | ||
free(jpg_buffer); | ||
|
||
// DDDD OOO N N EEEEEEE | ||
// D DDD O O NN N E | ||
// D DD O O N N N E | ||
// D D O O N N N E | ||
// D D O O N N N EEEE | ||
// D D O O N N N E | ||
// D DD O O N N N E | ||
// D DDD O O N NN E | ||
// DDDD OOO N N EEEEEEE | ||
|
||
// Write the decompressed bitmap out to a ppm file, just to make sure | ||
// it worked. | ||
fd = open("output.ppm", O_CREAT | O_WRONLY, 0666); | ||
char buf[1024]; | ||
|
||
rc = sprintf(buf, "P6 %d %d 255\n", width, height); | ||
write(fd, buf, rc); // Write the PPM image header before data | ||
write(fd, bmp_buffer, bmp_size); // Write out all RGB pixel data | ||
|
||
close(fd); | ||
free(bmp_buffer); | ||
|
||
printf("End of decompression\n"); | ||
return EXIT_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Copyright 2014 The Emscripten Authors. All rights reserved. | ||
# Emscripten is available under two separate licenses, the MIT license and the | ||
# University of Illinois/NCSA Open Source License. Both these licenses can be | ||
# found in the LICENSE file. | ||
|
||
import os | ||
import shutil | ||
import logging | ||
|
||
VERSION = '9c' | ||
|
||
|
||
def get(ports, settings, shared): | ||
if settings.USE_LIBJPEG != 1: | ||
return [] | ||
|
||
ports.fetch_project('libjpeg', 'https://dl.bintray.com/homebrew/mirror/jpeg-9c.tar.gz', 'jpeg-9c') | ||
|
||
libname = ports.get_lib_name('libjpeg') | ||
|
||
def create(): | ||
logging.info('building port: libjpeg') | ||
|
||
source_path = os.path.join(ports.get_dir(), 'libjpeg', 'jpeg-9c') | ||
dest_path = os.path.join(shared.Cache.get_path('ports-builds'), 'libjpeg') | ||
|
||
shutil.rmtree(dest_path, ignore_errors=True) | ||
shutil.copytree(source_path, dest_path) | ||
|
||
open(os.path.join(dest_path, 'jconfig.h'), 'w').write(jconfig_h) | ||
|
||
final = os.path.join(ports.get_build_dir(), 'libjpeg', libname) | ||
ports.build_port( | ||
dest_path, final, | ||
exclude_files=[ | ||
'ansi2knr.c', 'cjpeg.c', 'ckconfig.c', 'djpeg.c', 'example.c', | ||
'jmemansi.c', 'jmemdos.c', 'jmemmac.c', 'jmemname.c', | ||
'jpegtran.c', 'rdjpgcom.c', 'wrjpgcom.c', | ||
] | ||
) | ||
return final | ||
|
||
return [shared.Cache.get(libname, create, what='port')] | ||
|
||
|
||
def clear(ports, shared): | ||
shared.Cache.erase_file(ports.get_lib_name('libjpeg')) | ||
|
||
|
||
def process_args(ports, args, settings, shared): | ||
if settings.USE_LIBJPEG == 1: | ||
get(ports, settings, shared) | ||
args += ['-Xclang', '-isystem' + os.path.join(shared.Cache.get_path('ports-builds'), 'libjpeg')] | ||
return args | ||
|
||
|
||
def show(): | ||
return 'libjpeg (USE_LIBJPEG=1; BSD license)' | ||
|
||
|
||
jconfig_h = '''/* jconfig.h. Generated from jconfig.cfg by configure. */ | ||
/* jconfig.cfg --- source file edited by configure script */ | ||
/* see jconfig.txt for explanations */ | ||
#define HAVE_PROTOTYPES 1 | ||
#define HAVE_UNSIGNED_CHAR 1 | ||
#define HAVE_UNSIGNED_SHORT 1 | ||
/* #undef void */ | ||
/* #undef const */ | ||
/* #undef CHAR_IS_UNSIGNED */ | ||
#define HAVE_STDDEF_H 1 | ||
#define HAVE_STDLIB_H 1 | ||
#define HAVE_LOCALE_H 1 | ||
/* #undef NEED_BSD_STRINGS */ | ||
/* #undef NEED_SYS_TYPES_H */ | ||
/* #undef NEED_FAR_POINTERS */ | ||
/* #undef NEED_SHORT_EXTERNAL_NAMES */ | ||
/* Define this if you get warnings about undefined structures. */ | ||
/* #undef INCOMPLETE_TYPES_BROKEN */ | ||
/* Define "boolean" as unsigned char, not enum, on Windows systems. */ | ||
#ifdef _WIN32 | ||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ | ||
typedef unsigned char boolean; | ||
#endif | ||
#ifndef FALSE /* in case these macros already exist */ | ||
#define FALSE 0 /* values of boolean */ | ||
#endif | ||
#ifndef TRUE | ||
#define TRUE 1 | ||
#endif | ||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ | ||
#endif | ||
#ifdef JPEG_INTERNALS | ||
/* #undef RIGHT_SHIFT_IS_UNSIGNED */ | ||
#define INLINE __inline__ | ||
/* These are for configuring the JPEG memory manager. */ | ||
/* #undef DEFAULT_MAX_MEM */ | ||
/* #undef NO_MKTEMP */ | ||
#endif /* JPEG_INTERNALS */ | ||
#ifdef JPEG_CJPEG_DJPEG | ||
#define BMP_SUPPORTED /* BMP image file format */ | ||
#define GIF_SUPPORTED /* GIF image file format */ | ||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ | ||
/* #undef RLE_SUPPORTED */ | ||
#define TARGA_SUPPORTED /* Targa image file format */ | ||
/* #undef TWO_FILE_COMMANDLINE */ | ||
/* #undef NEED_SIGNAL_CATCHER */ | ||
/* #undef DONT_USE_B_MODE */ | ||
/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ | ||
/* #undef PROGRESS_REPORT */ | ||
#endif /* JPEG_CJPEG_DJPEG */ | ||
''' |