<s> import io <EOL> import copy <EOL> import random <EOL> import click <EOL> from itertools import tee , izip <EOL> from PIL import Image <EOL> def pairwise ( iterable ) : <EOL> """<STR_LIT>""" <EOL> a , b = tee ( iterable ) <EOL> next ( b , None ) <EOL> return izip ( a , b ) <EOL> class Jpeg ( object ) : <EOL> def __init__ ( self , image_bytes , amount , seed , iterations ) : <EOL> self . bytes = image_bytes <EOL> self . new_bytes = None <EOL> try : <EOL> self . header_length = self . get_header_length ( ) <EOL> except ValueError as e : <EOL> raise click . BadParameter ( message = e . message ) <EOL> self . parameters = { <EOL> '<STR_LIT>' : amount , <EOL> '<STR_LIT>' : seed , <EOL> '<STR_LIT>' : iterations <EOL> } <EOL> self . glitch_bytes ( ) <EOL> def get_header_length ( self ) : <EOL> """<STR_LIT>""" <EOL> for i , pair in enumerate ( pairwise ( self . bytes ) ) : <EOL> if pair [ <NUM_LIT:0> ] == <NUM_LIT:255> and pair [ <NUM_LIT:1> ] == <NUM_LIT> : <EOL> result = i + <NUM_LIT:2> <EOL> return result <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> def glitch_bytes ( self ) : <EOL> """<STR_LIT>""" <EOL> amount = self . parameters [ '<STR_LIT>' ] / <NUM_LIT:100> <EOL> seed = self . parameters [ '<STR_LIT>' ] / <NUM_LIT:100> <EOL> iterations = self . parameters [ '<STR_LIT>' ] <EOL> new_bytes = copy . copy ( self . bytes ) <EOL> for i in ( xrange ( iterations ) ) : <EOL> max_index = len ( self . bytes ) - self . header_length - <NUM_LIT:4> <EOL> px_min = int ( ( max_index / iterations ) * i ) <EOL> px_max = int ( ( max_index / iterations ) * ( i + <NUM_LIT:1> ) ) <EOL> delta = ( px_max - px_min ) <EOL> px_i = int ( px_min + ( delta * seed ) ) <EOL> if ( px_i > max_index ) : <EOL> px_i = max_index <EOL> byte_index = self . header_length + px_i <EOL> new_bytes [ byte_index ] = int ( amount * <NUM_LIT> ) <EOL> self . new_bytes = new_bytes <EOL> def save_image ( self , name ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> try : <EOL> stream = io . BytesIO ( self . new_bytes ) <EOL> im = Image . open ( stream ) <EOL> im . save ( name ) <EOL> return <EOL> except IOError : <EOL> if self . parameters [ '<STR_LIT>' ] == <NUM_LIT:1> : <EOL> raise click . BadParameter ( message = '<STR_LIT>' , param_hint = [ '<STR_LIT:image>' ] ) <EOL> self . parameters [ '<STR_LIT>' ] -= <NUM_LIT:1> <EOL> self . glitch_bytes ( ) <EOL> @ click . command ( ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , type = click . IntRange ( <NUM_LIT:0> , <NUM_LIT> , clamp = True ) , <EOL> default = random . randint ( <NUM_LIT:0> , <NUM_LIT> ) , help = "<STR_LIT>" ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , type = click . IntRange ( <NUM_LIT:0> , <NUM_LIT> , clamp = True ) , <EOL> default = random . randint ( <NUM_LIT:0> , <NUM_LIT> ) , help = "<STR_LIT>" ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , type = click . IntRange ( <NUM_LIT:0> , <NUM_LIT> , clamp = True ) , <EOL> default = random . randint ( <NUM_LIT:0> , <NUM_LIT> ) , help = "<STR_LIT>" ) <EOL> @ click . option ( '<STR_LIT>' , is_flag = True , help = "<STR_LIT>" ) <EOL> @ click . option ( '<STR_LIT>' , '<STR_LIT>' , help = "<STR_LIT>" ) <EOL> @ click . argument ( '<STR_LIT:image>' , type = click . File ( '<STR_LIT:rb>' ) ) <EOL> def cli ( image , amount , seed , iterations , jpg , output ) : <EOL> image_bytes = bytearray ( image . read ( ) ) <EOL> jpeg = Jpeg ( image_bytes , amount , seed , iterations ) <EOL> click . echo ( "<STR_LIT>" ) <EOL> for key , value in jpeg . parameters . iteritems ( ) : <EOL> click . echo ( message = key + '<STR_LIT>' + str ( value ) ) <EOL> if output : <EOL> name = output . rsplit ( '<STR_LIT:.>' ) [ <NUM_LIT:0> ] <EOL> else : <EOL> name = image . name . rsplit ( '<STR_LIT:.>' ) [ <NUM_LIT:0> ] + "<STR_LIT>" <EOL> name += '<STR_LIT:%s>' % ( '<STR_LIT>' if jpg else '<STR_LIT>' ) <EOL> jpeg . save_image ( name ) <EOL> output = "<STR_LIT>" % name <EOL> click . echo ( output ) </s>
