TJTransformer.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (C)2011, 2013-2015 D. R. Commander. All Rights Reserved.
  3. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * - Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * - Redistributions in binary form must reproduce the above copyright notice,
  11. * this list of conditions and the following disclaimer in the documentation
  12. * and/or other materials provided with the distribution.
  13. * - Neither the name of the libjpeg-turbo Project nor the names of its
  14. * contributors may be used to endorse or promote products derived from this
  15. * software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. package org.libjpegturbo.turbojpeg;
  30. /**
  31. * TurboJPEG lossless transformer
  32. */
  33. public class TJTransformer extends TJDecompressor {
  34. /**
  35. * Create a TurboJPEG lossless transformer instance.
  36. */
  37. public TJTransformer() throws TJException {
  38. init();
  39. }
  40. /**
  41. * Create a TurboJPEG lossless transformer instance and associate the JPEG
  42. * image stored in <code>jpegImage</code> with the newly created instance.
  43. *
  44. * @param jpegImage JPEG image buffer (size of the JPEG image is assumed to
  45. * be the length of the array.) This buffer is not modified.
  46. */
  47. public TJTransformer(byte[] jpegImage) throws TJException {
  48. init();
  49. setSourceImage(jpegImage, jpegImage.length);
  50. }
  51. /**
  52. * Create a TurboJPEG lossless transformer instance and associate the JPEG
  53. * image of length <code>imageSize</code> bytes stored in
  54. * <code>jpegImage</code> with the newly created instance.
  55. *
  56. * @param jpegImage JPEG image buffer. This buffer is not modified.
  57. *
  58. * @param imageSize size of the JPEG image (in bytes)
  59. */
  60. public TJTransformer(byte[] jpegImage, int imageSize) throws TJException {
  61. init();
  62. setSourceImage(jpegImage, imageSize);
  63. }
  64. /**
  65. * Losslessly transform the JPEG image associated with this transformer
  66. * instance into one or more JPEG images stored in the given destination
  67. * buffers. Lossless transforms work by moving the raw coefficients from one
  68. * JPEG image structure to another without altering the values of the
  69. * coefficients. While this is typically faster than decompressing the
  70. * image, transforming it, and re-compressing it, lossless transforms are not
  71. * free. Each lossless transform requires reading and performing Huffman
  72. * decoding on all of the coefficients in the source image, regardless of the
  73. * size of the destination image. Thus, this method provides a means of
  74. * generating multiple transformed images from the same source or of applying
  75. * multiple transformations simultaneously, in order to eliminate the need to
  76. * read the source coefficients multiple times.
  77. *
  78. * @param dstBufs an array of image buffers. <code>dstbufs[i]</code> will
  79. * receive a JPEG image that has been transformed using the parameters in
  80. * <code>transforms[i]</code>. Use {@link TJ#bufSize} to determine the
  81. * maximum size for each buffer based on the transformed or cropped width and
  82. * height and the level of subsampling used in the source image.
  83. *
  84. * @param transforms an array of {@link TJTransform} instances, each of
  85. * which specifies the transform parameters and/or cropping region for the
  86. * corresponding transformed output image
  87. *
  88. * @param flags the bitwise OR of one or more of
  89. * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
  90. */
  91. public void transform(byte[][] dstBufs, TJTransform[] transforms,
  92. int flags) throws TJException {
  93. if (jpegBuf == null)
  94. throw new IllegalStateException("JPEG buffer not initialized");
  95. transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms,
  96. flags);
  97. }
  98. /**
  99. * Losslessly transform the JPEG image associated with this transformer
  100. * instance and return an array of {@link TJDecompressor} instances, each of
  101. * which has a transformed JPEG image associated with it.
  102. *
  103. * @param transforms an array of {@link TJTransform} instances, each of
  104. * which specifies the transform parameters and/or cropping region for the
  105. * corresponding transformed output image
  106. *
  107. * @param flags the bitwise OR of one or more of
  108. * {@link TJ#FLAG_BOTTOMUP TJ.FLAG_*}
  109. *
  110. * @return an array of {@link TJDecompressor} instances, each of
  111. * which has a transformed JPEG image associated with it.
  112. */
  113. public TJDecompressor[] transform(TJTransform[] transforms, int flags)
  114. throws TJException {
  115. byte[][] dstBufs = new byte[transforms.length][];
  116. if (jpegWidth < 1 || jpegHeight < 1)
  117. throw new IllegalStateException("JPEG buffer not initialized");
  118. for (int i = 0; i < transforms.length; i++) {
  119. int w = jpegWidth, h = jpegHeight;
  120. if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
  121. if (transforms[i].width != 0) w = transforms[i].width;
  122. if (transforms[i].height != 0) h = transforms[i].height;
  123. }
  124. dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)];
  125. }
  126. TJDecompressor[] tjd = new TJDecompressor[transforms.length];
  127. transform(dstBufs, transforms, flags);
  128. for (int i = 0; i < transforms.length; i++)
  129. tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
  130. return tjd;
  131. }
  132. /**
  133. * Returns an array containing the sizes of the transformed JPEG images
  134. * generated by the most recent transform operation.
  135. *
  136. * @return an array containing the sizes of the transformed JPEG images
  137. * generated by the most recent transform operation.
  138. */
  139. public int[] getTransformedSizes() {
  140. if (transformedSizes == null)
  141. throw new IllegalStateException("No image has been transformed yet");
  142. return transformedSizes;
  143. }
  144. private native void init() throws TJException;
  145. private native int[] transform(byte[] srcBuf, int srcSize, byte[][] dstBufs,
  146. TJTransform[] transforms, int flags) throws TJException;
  147. static {
  148. TJLoader.load();
  149. }
  150. private int[] transformedSizes = null;
  151. }