Guest User

Ui, cat maid, Miku

a guest
Apr 15th, 2019
366
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. set -x -e
  3. # This creates an JPEG file with three different appearances depending on how the image is decoded.
  4. # Ui will appear when using a decoder without integer overflows.
  5. # A cat maid will appear when using a decoder that wraps the DCT coefficients (after multiplication by the quantization table) into the range [-8192..8191].
  6. # Miku will appear when using a decoder that wraps the final Y, Cb, Cr values into the range 128 + [-512..512].
  7. # The dct* tools are available at https://gitgud.io/dcttransform/dcttransform
  8.  
  9. # Download the original images.
  10. curl https://raikou1.donmai.us/49/0f/__hirasawa_ui_k_on__490fc72508f093d39d489de73fc034bd.jpg > ui.jpg
  11. curl https://raikou1.donmai.us/75/5c/__original_drawn_by_moonyan__755cf95729cb727b5e5d08149a527804.jpg > catmaid.jpg
  12. curl https://danbooru.donmai.us/data/__nakano_miku_go_toubun_no_hanayome_drawn_by_mery_apfl0515__ff3cd29d48e5bd98b8318dd225a1c828.png > miku.png
  13.  
  14. # The quantization table used in the files created.
  15. # All values that will be used are set to 32.
  16. # The last entry (unused) has been set to a large value because it seems to force some programs to use one of the decoding methods I'm targeting.
  17. (for i in {1..63}; do echo 32; done; echo 4096) > qtable.txt
  18.  
  19. # Create two color palettes.
  20. # 8colors.jpg contains the colors obtained when pushing Y, Cb, Cr outside the valid ranges.
  21. # 8legal.jpg contains the colors obtained by setting Y, Cb, Cr to 128 +/- 32.
  22. convert -size 512x512 xc:red ppm:- | cjpeg -qtables qtable.txt -qslots 0 -sample 1x1 > blank512.jpg
  23. dcttransform 'dct.map((x,i) => {if (i%64) return 0; x=(i>>6)%64; c=(i>>18); return 64*((Math.floor(x/8)&(1<<c)) ? 1 : -1)})' blank512.jpg > 8colors.jpg
  24. dcttransform 'dct.map((x,i) => {if (i%64) return 0; x=(i>>6)%64; c=(i>>18); return 8*((Math.floor(x/8)&(1<<c)) ? 1 : -1)})' blank512.jpg > 8legal.jpg
  25.  
  26. # Quantize all images to the colors in 8colors.jpg.
  27. # Also pixelate into 1x8 blocks. I don't have this working yet when vertical AC components are involved.
  28. # The images are desaturated a bit before dithering as it seems to improve results.
  29. for f in ui.jpg catmaid.jpg miku.png; do convert "$f" -resize 100%x12.5% -colorspace YCbCr +level 25% -colorspace sRGB -remap 8colors.jpg -scale 100%x800% "${f%.*}-quant.ppm"; done
  30.  
  31. # Remap all images from the 8colors.jpg colors to the 8legal.jpg colors and JPEG compress them using our quantization table.
  32. # Miku will be JPEG compressed at a later step.
  33. for f in ui catmaid miku; do convert "$f-quant.ppm" +dither -remap 8legal.jpg "$f-legal.ppm"; done
  34. for f in ui catmaid; do cjpeg -qtables qtable.txt -qslots 0 -sample 1x1 "$f-legal.ppm" > "$f-legal.jpg"; done
  35.  
  36. # Ui is encoded in the DCT coefficients by adding/subtracting 512 (+/- 16384 after multiplication by the quantization table).
  37. # This will be discarded in the decoders that show the cat maid.
  38. # The file produced here will be further multiplied by 128, but for now we need it to be in the legal range.
  39. dcttransform 'n=dct.length; a=new Uint16Array(n); for(i=0;i<n;i++) a[i]=Math.sign(dct[i])*4; a' ui-legal.jpg > ui-enc.jpg
  40.  
  41. # Decompose Ui into Y, Cb, Cr components.
  42. dctextract < ui-enc.jpg > ui-enc.dct
  43. nbytes=$(stat -c %s ui-enc.dct)
  44. for i in {0..2}; do (tail -c +$((i*nbytes/3+1)) ui-enc.dct | head -c $((nbytes/3)); head -c $((2*nbytes/3)) /dev/zero) > "ui-enc-$i.dct"; done
  45. for i in {0..2}; do dctreplace "ui-enc-$i.dct" < ui-enc.jpg > "ui-enc-$i.jpg"; done
  46.  
  47. # Decompose Miku into Y, Cb, Cr components.
  48. convert miku-legal.ppm -colorspace YCbCr -separate miku-legal-%d.ppm
  49.  
  50. # Miku is encoded in the last 10 bits of the final Y, Cb, Cr values, as an offset of +/- 256 from one of the wrap points (128 - 512 + 1024n).
  51. # Ui has contaminated these bits and needs to be corrected.
  52. # The correction is done before JPEG compression.
  53. # The cat maid (not yet added) will contribute +/- 512.
  54. # Here, the 128 + [-512..512] range is compressed into 128 + [-128..127]; it will be multiplied by -4 later.
  55. for i in {0..2}; do convert "miku-legal-$i.ppm" "ui-enc-$i.jpg" -fx 'mod(2*u+32*v+128/255,256/255)' "miku-enc-$i.ppm"; done
  56. for i in {0..2}; do cjpeg -qtables qtable.txt -qslots 0 -sample 1x1 "miku-enc-$i.ppm" > "miku-enc-$i.jpg"; done
  57.  
  58. # Recombine channels.
  59. for i in {0..2}; do dctextract < "miku-enc-$i.jpg" | head -c $((nbytes/3)); done > miku-enc.dct
  60.  
  61. # Combine Ui, cat maid, and Miku (+ Ui correction).
  62. dctextract < catmaid-legal.jpg > catmaid-legal.dct
  63. cat ui-enc.dct catmaid-legal.dct miku-enc.dct | dcteval 'n=dct.length/3; a=new Uint16Array(n); for(i=0;i<n;i++) a[i]=128*dct[i]+16*dct[i+n]-4*dct[i+2*n]; a' > ucm.dct
  64. dctreplace ucm.dct < ui-legal.jpg > ucm.jpg
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×