diff --git a/mjpeg/__init__.py b/mjpeg/__init__.py index 43cf7dd..85c0bf9 100644 --- a/mjpeg/__init__.py +++ b/mjpeg/__init__.py @@ -2,7 +2,7 @@ from libmjsteg import Jsteg -__all__ = ['Jpeg','colorMap','diffblock','diffblocks'] +__all__ = ['Jpeg', 'colorMap', 'diffblock', 'diffblocks'] # We need standard components from :mod:`numpy`, and some auxiliary # functions from submodules. @@ -16,6 +16,7 @@ import pylab as plt import base from dct import bdct, ibdct +from compress import * # The colour codes are defined in the JPEG standard. We store # them here for easy reference by name:: @@ -55,7 +56,7 @@ class Jpeg(Jsteg): Jsteg.__init__(self, file, **kw) self.verbosity = verbosity if verbosity > 0: - print "[Jpeg.__init__] Image size %ix%i" % (self.coef_arrays[0].shape) + print "[Jpeg.__init__] Image size %ix%i" % (self.image_width, self.image_height) if key != None: self.key = key elif rndkey: @@ -290,6 +291,47 @@ class Jpeg(Jsteg): self.coef_arrays[cID][v:v + 8, h:h + 8] = blocks[i, j] self.Jsetblock(j, i, cID, bytearray(blocks[i, j].astype(np.int16))) + def getSize(self): + return self.image_width, self.image_height + + def getQuality(self): + """ + Qaulity rating algorithm from ImageMagick. + + e.g. + find ./ -name "*.jpg" | xargs -i sh -c "echo -n {} && identify -quiet -verbose {} |grep -E 'Quality' " + + Ref - http://stackoverflow.com/questions/2024947/is-it-possible-to-tell-the-quality-level-of-a-jpeg,http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20235 + """ + table0 = self.quant_tables[0].ravel() + table1 = self.quant_tables[1].ravel() + sum0 = np.sum(table0) + sum1 = np.sum(table1) + quality = None + + if sum0 != None: + if sum1 != None: + sum = sum0 + sum1 + qvalue = table0[2] + table0[53] + table1[0] + table1[-1] + hashtable = bi_hash + sumtable = bi_sum + else: + sum = sum0 + qvalue = table0[2] + table0[53] + hashtable = single_hash + sumtable = single_sum + else: + raise Exception("Quantization Tables Illegal") + return None + + for i in range(100): + if qvalue >= hashtable[i] or sum >= sumtable[i]: + break + quality = i + 1 + + return quality + + # Decompression # ------------- @@ -404,3 +446,13 @@ def diffblocks(a, b): cnt += 1 return diff, cnt + + + + + + + + + + diff --git a/mjpeg/__init__.pyc b/mjpeg/__init__.pyc index 31a8f63..f1c0083 100644 Binary files a/mjpeg/__init__.pyc and b/mjpeg/__init__.pyc differ diff --git a/mjpeg/compress.py b/mjpeg/compress.py index 9b6d041..98e9a84 100644 --- a/mjpeg/compress.py +++ b/mjpeg/compress.py @@ -5,179 +5,94 @@ from pylab import * # The standard quantisation tables for JPEG:: -table0 = array( - [ [ 16, 11, 10, 16, 24, 40, 51, 61 ], - [ 12, 12, 14, 19, 26, 58, 60, 55 ], - [ 14, 13, 16, 24, 40, 57, 69, 56 ], - [ 14, 17, 22, 29, 51, 87, 80, 62 ], - [ 18, 22, 37, 56, 68, 109, 103, 77 ], - [ 24, 35, 55, 64, 81, 104, 113, 92 ], - [ 49, 64, 78, 87, 103, 121, 120, 101 ], - [ 72, 92, 95, 98, 112, 100, 103, 99 ] ] ) +orig_table0 = array( + [[16, 11, 10, 16, 24, 40, 51, 61], + [12, 12, 14, 19, 26, 58, 60, 55], + [14, 13, 16, 24, 40, 57, 69, 56], + [14, 17, 22, 29, 51, 87, 80, 62], + [18, 22, 37, 56, 68, 109, 103, 77], + [24, 35, 55, 64, 81, 104, 113, 92], + [49, 64, 78, 87, 103, 121, 120, 101], + [72, 92, 95, 98, 112, 100, 103, 99]]) + +orig_table1 = array( + [[17, 18, 24, 47, 99, 99, 99, 99], + [18, 21, 26, 66, 99, 99, 99, 99], + [24, 26, 56, 99, 99, 99, 99, 99], + [47, 66, 99, 99, 99, 99, 99, 99], + [99, 99, 99, 99, 99, 99, 99, 99], + [99, 99, 99, 99, 99, 99, 99, 99], + [99, 99, 99, 99, 99, 99, 99, 99], + [99, 99, 99, 99, 99, 99, 99, 99]]) + +bi_hash = [ + 1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645, + 632, 623, 613, 607, 600, 594, 589, 585, 581, 571, + 555, 542, 529, 514, 494, 474, 457, 439, 424, 410, + 397, 386, 373, 364, 351, 341, 334, 324, 317, 309, + 299, 294, 287, 279, 274, 267, 262, 257, 251, 247, + 243, 237, 232, 227, 222, 217, 213, 207, 202, 198, + 192, 188, 183, 177, 173, 168, 163, 157, 153, 148, + 143, 139, 132, 128, 125, 119, 115, 108, 104, 99, + 94, 90, 84, 79, 74, 70, 64, 59, 55, 49, + 45, 40, 34, 30, 25, 20, 15, 11, 6, 4, + 0 +] + +bi_sum = [ + 32640, 32635, 32266, 31495, 30665, 29804, 29146, 28599, 28104, + 27670, 27225, 26725, 26210, 25716, 25240, 24789, 24373, 23946, + 23572, 22846, 21801, 20842, 19949, 19121, 18386, 17651, 16998, + 16349, 15800, 15247, 14783, 14321, 13859, 13535, 13081, 12702, + 12423, 12056, 11779, 11513, 11135, 10955, 10676, 10392, 10208, + 9928, 9747, 9564, 9369, 9193, 9017, 8822, 8639, 8458, + 8270, 8084, 7896, 7710, 7527, 7347, 7156, 6977, 6788, + 6607, 6422, 6236, 6054, 5867, 5684, 5495, 5305, 5128, + 4945, 4751, 4638, 4442, 4248, 4065, 3888, 3698, 3509, + 3326, 3139, 2957, 2775, 2586, 2405, 2216, 2037, 1846, + 1666, 1483, 1297, 1109, 927, 735, 554, 375, 201, + 128, 0 +] + +single_hash = [ + 510, 505, 422, 380, 355, 338, 326, 318, 311, 305, + 300, 297, 293, 291, 288, 286, 284, 283, 281, 280, + 279, 278, 277, 273, 262, 251, 243, 233, 225, 218, + 211, 205, 198, 193, 186, 181, 177, 172, 168, 164, + 158, 156, 152, 148, 145, 142, 139, 136, 133, 131, + 129, 126, 123, 120, 118, 115, 113, 110, 107, 105, + 102, 100, 97, 94, 92, 89, 87, 83, 81, 79, + 76, 74, 70, 68, 66, 63, 61, 57, 55, 52, + 50, 48, 44, 42, 39, 37, 34, 31, 29, 26, + 24, 21, 18, 16, 13, 11, 8, 6, 3, 2, + 0 +] + +single_sum = [ + 16320, 16315, 15946, 15277, 14655, 14073, 13623, 13230, 12859, + 12560, 12240, 11861, 11456, 11081, 10714, 10360, 10027, 9679, + 9368, 9056, 8680, 8331, 7995, 7668, 7376, 7084, 6823, + 6562, 6345, 6125, 5939, 5756, 5571, 5421, 5240, 5086, + 4976, 4829, 4719, 4616, 4463, 4393, 4280, 4166, 4092, + 3980, 3909, 3835, 3755, 3688, 3621, 3541, 3467, 3396, + 3323, 3247, 3170, 3096, 3021, 2952, 2874, 2804, 2727, + 2657, 2583, 2509, 2437, 2362, 2290, 2211, 2136, 2068, + 1996, 1915, 1858, 1773, 1692, 1620, 1552, 1477, 1398, + 1326, 1251, 1179, 1109, 1031, 961, 884, 814, 736, + 667, 592, 518, 441, 369, 292, 221, 151, 86, + 64, 0 +] -table1 = array( - [ [ 17, 18, 24, 47, 99, 99, 99, 99 ], - [ 18, 21, 26, 66, 99, 99, 99, 99 ], - [ 24, 26, 56, 99, 99, 99, 99, 99 ], - [ 47, 66, 99, 99, 99, 99, 99, 99 ], - [ 99, 99, 99, 99, 99, 99, 99, 99 ], - [ 99, 99, 99, 99, 99, 99, 99, 99 ], - [ 99, 99, 99, 99, 99, 99, 99, 99 ], - [ 99, 99, 99, 99, 99, 99, 99, 99 ] ] ) -# The quantTable function seems straight forward, -# but has not been tested. -def quantTable(quality=50,tnum=0,force_baseline=False): - if quality <= 0: quality = 1 - elif quality > 100: quality = 100 - if quality < 50: quality = 5000 / quality - else: quality = 200 - quality*2 - t = floor( (t * quality + 50) /100 ) - t[t<1] = 1 - if (force_baseline): t[t>255] = 255 - else: t[t>32767] = 32767 # max quantizer needed for 12 bits - return t -# I don't think this works. -def bdctmtx(n=8): - (c,r) = meshgrid(range(n), range(n)) - (c0,r0) = meshgrid(r.flatten()); - (c1,r1) = meshgrid(c.flatten()); - x = sqrt(float(2) / n) - x *= cos( pi * (2*c + 1) * r / (2 * n)); - x[1,:] = x[1,:] / sqrt(2); - return x[r0+c0*n+1] * x[r1+c1*n+1] -def im2vec(im,blksize=8,padsize=0): - """Reshape 2D image blocks into an array of column vectors - V=im2vec(im,blksize=8,padsize=0) - - IM is an image to be separated into non-overlapping blocks and - reshaped into an MxN array containing N blocks reshaped into Mx1 - column vectors. im2vec is designed to be the inverse of vec2im. - - BLKSIZE is a scalar or 1x2 vector indicating the size of the blocks. - - PADSIZE is a scalar or 1x2 vector indicating the amount of vertical - and horizontal space to be skipped between blocks in the image. - Default is [0 0]. If PADSIZE is a scalar, the same amount of space - is used for both directions. PADSIZE must be non-negative (blocks - must be non-overlapping). - - ROWS indicates the number of rows of blocks found in the image. - COLS indicates the number of columns of blocks found in the image. - """ - - blksize=blksize + array( [0,0] ) - padsize=padsize + array( [0,0] ) - if ( any( padsize < 0 ) ): - raise InputException, "Pad size must be non-negative." - - (height,width) = im.shape - (y,x) = blksize + padsize - - rows = int( ( height + padsize[0] ) / y ) - cols = int( ( width + padsize[1] ) / x ) - - T = zeros( [y*rows,x*cols] ) - - imy = y*rows - padsize[0] - imx = x*cols - padsize[1] - - T[0:imy,0:imx] = im[0:imy,0:imx] - - T = reshape(T, [ cols, y, rows, x ] ) - T = transpose( T, [0,2,1,3]) - T = reshape( T, [ y, x, rows*cols ] ) - V = T[0:blksize[0], 0:blksize[1], 0:(rows*cols) ] - - return (reshape( V, [ rows*cols, y*x ] ), rows, cols) - -def vec2im(V,blksize=None,padsize=0,rows=None,cols=None): - """Reshape and combine column vectors into a 2D image - - V is an MxN array containing N Mx1 column vectors which will be reshaped - and combined to form image IM. - - PADSIZE is a scalar or a 1x2 vector indicating the amount of vertical and - horizontal space to be added as a border between the reshaped vectors. - Default is [0 0]. If PADSIZE is a scalar, the same amount of space is used - for both directions. - - BLKSIZE is a scalar or a 1x2 vector indicating the size of the blocks. - Default is sqrt(M). - - ROWS indicates the number of rows of blocks in the image. Default is - floor(sqrt(N)). - - COLS indicates the number of columns of blocks in the image. Default - is ceil(N/ROWS). - """ - - (n,m) = V.shape - - padsize = padsize + array( [0,0] ) - if ( any( padsize < 0 ) ): - raise InputException, "Pad size must be non-negative." - - if blksize == None: - bsize = floor(sqrt(m)) - - blksize = blksize + array([0,0]) - if prod(blksize) != m: - print m, blksize - raise InputException, 'Block size does not match size of input vectors.' - - if rows == None: - rows = floor(sqrt(n)) - if cols == None: - cols = ceil(n/rows) - -# make image -# -# :: - - (y,x) = blksize + padsize - -# zero() returns float64 and causes T to become a floating point array -# This is a bug; integer input should give integer return -# -# :: - - T = zeros( [rows*cols, y, x] ) - T[0:n, 0:blksize[0], 0:blksize[1]] = \ - reshape( V, [n, blksize[0], blksize[1] ] ) - T = reshape(T, [rows,cols,y,x] ) - T = transpose( T, [0,2,1,3] ) - T = reshape(T, [y*rows,x*cols] ) - return T[0:(y*rows-padsize[0]), 0:(x*cols-padsize[1]) ] - -def quantise(C,Q): - """Quantise DCT coefficients using the quantisation matrix Q.""" - return C / repmat( Q, C.shape / Q.shape ) - -def dequantise(C,Q): - """Dequantise JPEG coefficients using the quantisation matrix Q.""" - return C * repmat( Q, C.shape / Q.shape ) - -def bdct(A,blksize=8): - """Blocked discrete cosine transform for JPEG compression.""" - dctm = bdctmtx(blksize) - (v,r,c) = im2vec(a,blksize) - return vec2im(dot(dctm,v),blksize,rows=r,cols=c) - -def ibdct(A,blksize=8): - """Inverse blocked discrete cosine transform""" - dctm = bdctmtx(blksize) - (v,r,c) = im2vec(a,blksize) - return vec2im(dot(transpose(dctm),v),blksize,rows=r,cols=c) diff --git a/mjpeg/compress.pyc b/mjpeg/compress.pyc new file mode 100644 index 0000000..75ac708 Binary files /dev/null and b/mjpeg/compress.pyc differ diff --git a/msteg/steganalysis/MPB.py b/msteg/steganalysis/MPB.py index 0464b21..4184dbb 100644 --- a/msteg/steganalysis/MPB.py +++ b/msteg/steganalysis/MPB.py @@ -16,6 +16,10 @@ import pickle import cv2 from sklearn import svm +# from numba import jit + + + base_dir = '/home/hadoop/data/HeadShoulder/' @@ -82,7 +86,7 @@ class MPB(StegBase): # 1.422729s return TPM - + @jit def get_trans_prob_mat(self, ciq, T=4): """ Calculate Transition Probability Matrix. diff --git a/msteg/steganalysis/MPB.pyc b/msteg/steganalysis/MPB.pyc index a624d5b..e99c559 100644 Binary files a/msteg/steganalysis/MPB.pyc and b/msteg/steganalysis/MPB.pyc differ diff --git a/msteg/steganalysis/__init__.pyc b/msteg/steganalysis/__init__.pyc index 1ddc5fb..9e2dea7 100644 Binary files a/msteg/steganalysis/__init__.pyc and b/msteg/steganalysis/__init__.pyc differ diff --git a/msteg/steganography/F4.pyc b/msteg/steganography/F4.pyc index 3921dee..380c741 100644 Binary files a/msteg/steganography/F4.pyc and b/msteg/steganography/F4.pyc differ diff --git a/msteg/steganography/F5.pyc b/msteg/steganography/F5.pyc index b9a9728..0a56160 100644 Binary files a/msteg/steganography/F5.pyc and b/msteg/steganography/F5.pyc differ diff --git a/msteg/steganography/__init__.pyc b/msteg/steganography/__init__.pyc index 33f0bf3..b5a0244 100644 Binary files a/msteg/steganography/__init__.pyc and b/msteg/steganography/__init__.pyc differ diff --git a/res/compress.py b/res/compress.py new file mode 100644 index 0000000..9b6d041 --- /dev/null +++ b/res/compress.py @@ -0,0 +1,183 @@ +## -*- coding: utf-8 -*- + + +from pylab import * + +# The standard quantisation tables for JPEG:: + +table0 = array( + [ [ 16, 11, 10, 16, 24, 40, 51, 61 ], + [ 12, 12, 14, 19, 26, 58, 60, 55 ], + [ 14, 13, 16, 24, 40, 57, 69, 56 ], + [ 14, 17, 22, 29, 51, 87, 80, 62 ], + [ 18, 22, 37, 56, 68, 109, 103, 77 ], + [ 24, 35, 55, 64, 81, 104, 113, 92 ], + [ 49, 64, 78, 87, 103, 121, 120, 101 ], + [ 72, 92, 95, 98, 112, 100, 103, 99 ] ] ) + +table1 = array( + [ [ 17, 18, 24, 47, 99, 99, 99, 99 ], + [ 18, 21, 26, 66, 99, 99, 99, 99 ], + [ 24, 26, 56, 99, 99, 99, 99, 99 ], + [ 47, 66, 99, 99, 99, 99, 99, 99 ], + [ 99, 99, 99, 99, 99, 99, 99, 99 ], + [ 99, 99, 99, 99, 99, 99, 99, 99 ], + [ 99, 99, 99, 99, 99, 99, 99, 99 ], + [ 99, 99, 99, 99, 99, 99, 99, 99 ] ] ) + +# The quantTable function seems straight forward, +# but has not been tested. + +def quantTable(quality=50,tnum=0,force_baseline=False): + if quality <= 0: quality = 1 + elif quality > 100: quality = 100 + if quality < 50: quality = 5000 / quality + else: quality = 200 - quality*2 + + t = floor( (t * quality + 50) /100 ) + + t[t<1] = 1 + + if (force_baseline): t[t>255] = 255 + else: t[t>32767] = 32767 # max quantizer needed for 12 bits + + return t + +# I don't think this works. + +def bdctmtx(n=8): + (c,r) = meshgrid(range(n), range(n)) + (c0,r0) = meshgrid(r.flatten()); + (c1,r1) = meshgrid(c.flatten()); + + x = sqrt(float(2) / n) + x *= cos( pi * (2*c + 1) * r / (2 * n)); + x[1,:] = x[1,:] / sqrt(2); + + return x[r0+c0*n+1] * x[r1+c1*n+1] + +def im2vec(im,blksize=8,padsize=0): + """Reshape 2D image blocks into an array of column vectors + + V=im2vec(im,blksize=8,padsize=0) + + IM is an image to be separated into non-overlapping blocks and + reshaped into an MxN array containing N blocks reshaped into Mx1 + column vectors. im2vec is designed to be the inverse of vec2im. + + BLKSIZE is a scalar or 1x2 vector indicating the size of the blocks. + + PADSIZE is a scalar or 1x2 vector indicating the amount of vertical + and horizontal space to be skipped between blocks in the image. + Default is [0 0]. If PADSIZE is a scalar, the same amount of space + is used for both directions. PADSIZE must be non-negative (blocks + must be non-overlapping). + + ROWS indicates the number of rows of blocks found in the image. + COLS indicates the number of columns of blocks found in the image. + """ + + blksize=blksize + array( [0,0] ) + padsize=padsize + array( [0,0] ) + if ( any( padsize < 0 ) ): + raise InputException, "Pad size must be non-negative." + + (height,width) = im.shape + (y,x) = blksize + padsize + + rows = int( ( height + padsize[0] ) / y ) + cols = int( ( width + padsize[1] ) / x ) + + T = zeros( [y*rows,x*cols] ) + + imy = y*rows - padsize[0] + imx = x*cols - padsize[1] + + T[0:imy,0:imx] = im[0:imy,0:imx] + + T = reshape(T, [ cols, y, rows, x ] ) + T = transpose( T, [0,2,1,3]) + T = reshape( T, [ y, x, rows*cols ] ) + V = T[0:blksize[0], 0:blksize[1], 0:(rows*cols) ] + + return (reshape( V, [ rows*cols, y*x ] ), rows, cols) + +def vec2im(V,blksize=None,padsize=0,rows=None,cols=None): + """Reshape and combine column vectors into a 2D image + + V is an MxN array containing N Mx1 column vectors which will be reshaped + and combined to form image IM. + + PADSIZE is a scalar or a 1x2 vector indicating the amount of vertical and + horizontal space to be added as a border between the reshaped vectors. + Default is [0 0]. If PADSIZE is a scalar, the same amount of space is used + for both directions. + + BLKSIZE is a scalar or a 1x2 vector indicating the size of the blocks. + Default is sqrt(M). + + ROWS indicates the number of rows of blocks in the image. Default is + floor(sqrt(N)). + + COLS indicates the number of columns of blocks in the image. Default + is ceil(N/ROWS). + """ + + (n,m) = V.shape + + padsize = padsize + array( [0,0] ) + if ( any( padsize < 0 ) ): + raise InputException, "Pad size must be non-negative." + + if blksize == None: + bsize = floor(sqrt(m)) + + blksize = blksize + array([0,0]) + if prod(blksize) != m: + print m, blksize + raise InputException, 'Block size does not match size of input vectors.' + + if rows == None: + rows = floor(sqrt(n)) + if cols == None: + cols = ceil(n/rows) + +# make image +# +# :: + + (y,x) = blksize + padsize + +# zero() returns float64 and causes T to become a floating point array +# This is a bug; integer input should give integer return +# +# :: + + T = zeros( [rows*cols, y, x] ) + T[0:n, 0:blksize[0], 0:blksize[1]] = \ + reshape( V, [n, blksize[0], blksize[1] ] ) + T = reshape(T, [rows,cols,y,x] ) + T = transpose( T, [0,2,1,3] ) + T = reshape(T, [y*rows,x*cols] ) + return T[0:(y*rows-padsize[0]), 0:(x*cols-padsize[1]) ] + +def quantise(C,Q): + """Quantise DCT coefficients using the quantisation matrix Q.""" + return C / repmat( Q, C.shape / Q.shape ) + +def dequantise(C,Q): + """Dequantise JPEG coefficients using the quantisation matrix Q.""" + return C * repmat( Q, C.shape / Q.shape ) + +def bdct(A,blksize=8): + """Blocked discrete cosine transform for JPEG compression.""" + dctm = bdctmtx(blksize) + (v,r,c) = im2vec(a,blksize) + return vec2im(dot(dctm,v),blksize,rows=r,cols=c) + +def ibdct(A,blksize=8): + """Inverse blocked discrete cosine transform""" + dctm = bdctmtx(blksize) + (v,r,c) = im2vec(a,blksize) + return vec2im(dot(transpose(dctm),v),blksize,rows=r,cols=c) + diff --git a/res/quality.c b/res/quality.c new file mode 100644 index 0000000..f1d35ae --- /dev/null +++ b/res/quality.c @@ -0,0 +1,134 @@ +static void JPEGSetImageQuality(struct jpeg_decompress_struct *jpeg_info, + Image *image) +{ + image->quality=UndefinedCompressionQuality; +#if defined(D_PROGRESSIVE_SUPPORTED) + if (image->compression == LosslessJPEGCompression) + { + image->quality=100; + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Quality: 100 (lossless)"); + } + else +#endif + { + ssize_t + j, + qvalue, + sum; + + register ssize_t + i; + + /* + Determine the JPEG compression quality from the quantization tables. + */ + sum=0; + for (i=0; i < NUM_QUANT_TBLS; i++) + { + if (jpeg_info->quant_tbl_ptrs[i] != NULL) + for (j=0; j < DCTSIZE2; j++) + sum+=jpeg_info->quant_tbl_ptrs[i]->quantval[j]; + } + if ((jpeg_info->quant_tbl_ptrs[0] != NULL) && + (jpeg_info->quant_tbl_ptrs[1] != NULL)) + { + ssize_t + hash[101] = + { + 1020, 1015, 932, 848, 780, 735, 702, 679, 660, 645, + 632, 623, 613, 607, 600, 594, 589, 585, 581, 571, + 555, 542, 529, 514, 494, 474, 457, 439, 424, 410, + 397, 386, 373, 364, 351, 341, 334, 324, 317, 309, + 299, 294, 287, 279, 274, 267, 262, 257, 251, 247, + 243, 237, 232, 227, 222, 217, 213, 207, 202, 198, + 192, 188, 183, 177, 173, 168, 163, 157, 153, 148, + 143, 139, 132, 128, 125, 119, 115, 108, 104, 99, + 94, 90, 84, 79, 74, 70, 64, 59, 55, 49, + 45, 40, 34, 30, 25, 20, 15, 11, 6, 4, + 0 + }, + sums[101] = + { + 32640, 32635, 32266, 31495, 30665, 29804, 29146, 28599, 28104, + 27670, 27225, 26725, 26210, 25716, 25240, 24789, 24373, 23946, + 23572, 22846, 21801, 20842, 19949, 19121, 18386, 17651, 16998, + 16349, 15800, 15247, 14783, 14321, 13859, 13535, 13081, 12702, + 12423, 12056, 11779, 11513, 11135, 10955, 10676, 10392, 10208, + 9928, 9747, 9564, 9369, 9193, 9017, 8822, 8639, 8458, + 8270, 8084, 7896, 7710, 7527, 7347, 7156, 6977, 6788, + 6607, 6422, 6236, 6054, 5867, 5684, 5495, 5305, 5128, + 4945, 4751, 4638, 4442, 4248, 4065, 3888, 3698, 3509, + 3326, 3139, 2957, 2775, 2586, 2405, 2216, 2037, 1846, + 1666, 1483, 1297, 1109, 927, 735, 554, 375, 201, + 128, 0 + }; + + qvalue=(ssize_t) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+ + jpeg_info->quant_tbl_ptrs[0]->quantval[53]+ + jpeg_info->quant_tbl_ptrs[1]->quantval[0]+ + jpeg_info->quant_tbl_ptrs[1]->quantval[DCTSIZE2-1]); + for (i=0; i < 100; i++) + { + if ((qvalue < hash[i]) && (sum < sums[i])) + continue; + if (((qvalue <= hash[i]) && (sum <= sums[i])) || (i >= 50)) + image->quality=(size_t) i+1; + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Quality: %.20g (%s)",(double) i+1,(qvalue <= hash[i]) && + (sum <= sums[i]) ? "exact" : "approximate"); + break; + } + } + else + if (jpeg_info->quant_tbl_ptrs[0] != NULL) + { + ssize_t + hash[101] = + { + 510, 505, 422, 380, 355, 338, 326, 318, 311, 305, + 300, 297, 293, 291, 288, 286, 284, 283, 281, 280, + 279, 278, 277, 273, 262, 251, 243, 233, 225, 218, + 211, 205, 198, 193, 186, 181, 177, 172, 168, 164, + 158, 156, 152, 148, 145, 142, 139, 136, 133, 131, + 129, 126, 123, 120, 118, 115, 113, 110, 107, 105, + 102, 100, 97, 94, 92, 89, 87, 83, 81, 79, + 76, 74, 70, 68, 66, 63, 61, 57, 55, 52, + 50, 48, 44, 42, 39, 37, 34, 31, 29, 26, + 24, 21, 18, 16, 13, 11, 8, 6, 3, 2, + 0 + }, + sums[101] = + { + 16320, 16315, 15946, 15277, 14655, 14073, 13623, 13230, 12859, + 12560, 12240, 11861, 11456, 11081, 10714, 10360, 10027, 9679, + 9368, 9056, 8680, 8331, 7995, 7668, 7376, 7084, 6823, + 6562, 6345, 6125, 5939, 5756, 5571, 5421, 5240, 5086, + 4976, 4829, 4719, 4616, 4463, 4393, 4280, 4166, 4092, + 3980, 3909, 3835, 3755, 3688, 3621, 3541, 3467, 3396, + 3323, 3247, 3170, 3096, 3021, 2952, 2874, 2804, 2727, + 2657, 2583, 2509, 2437, 2362, 2290, 2211, 2136, 2068, + 1996, 1915, 1858, 1773, 1692, 1620, 1552, 1477, 1398, + 1326, 1251, 1179, 1109, 1031, 961, 884, 814, 736, + 667, 592, 518, 441, 369, 292, 221, 151, 86, + 64, 0 + }; + + qvalue=(ssize_t) (jpeg_info->quant_tbl_ptrs[0]->quantval[2]+ + jpeg_info->quant_tbl_ptrs[0]->quantval[53]); + for (i=0; i < 100; i++) + { + if ((qvalue < hash[i]) && (sum < sums[i])) + continue; + if (((qvalue <= hash[i]) && (sum <= sums[i])) || (i >= 50)) + image->quality=(size_t) i+1; + if (image->debug != MagickFalse) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Quality: %.20g (%s)",(double) i+1,(qvalue <= hash[i]) && + (sum <= sums[i]) ? "exact" : "approximate"); + break; + } + } + } +} diff --git a/test_jpeg.py b/test_jpeg.py index 641d7a6..5e245af 100644 --- a/test_jpeg.py +++ b/test_jpeg.py @@ -167,7 +167,10 @@ if __name__ == '__main__': # test_bitbyte() - ima = mjpeg.Jpeg("res/test3.jpg", key=sample_key) + ima = mjpeg.Jpeg("res/lena.jpg", key=sample_key) + print ima.getQuality() + sys.exit(0) + # imb = mjpeg.Jpeg("res/new.jpg",key=sample_key) imc = mjpeg.Jpeg("res/steged.jpg", key=sample_key) print ima.Jgetcompdim(0) -- libgit2 0.21.2