diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 31c05ff..9c70bde 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/apng_library/build.gradle b/apng_library/build.gradle index f8bfbf2..0ef1836 100644 --- a/apng_library/build.gradle +++ b/apng_library/build.gradle @@ -10,7 +10,7 @@ android { versionCode 1 versionName "1.0.9" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -26,11 +26,11 @@ android { } dependencies { - implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'androidx.appcompat:appcompat:1.0.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'androidx.test:runner:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' implementation "org.jetbrains.anko:anko:$anko_version" diff --git a/apng_library/src/androidTest/java/oupson/apng/ExampleInstrumentedTest.java b/apng_library/src/androidTest/java/oupson/apng/ExampleInstrumentedTest.java index b223968..bf654ea 100644 --- a/apng_library/src/androidTest/java/oupson/apng/ExampleInstrumentedTest.java +++ b/apng_library/src/androidTest/java/oupson/apng/ExampleInstrumentedTest.java @@ -1,9 +1,8 @@ package oupson.apng; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; - +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/apng_library/src/main/java/oupson/apng/APNGDisassembler.kt b/apng_library/src/main/java/oupson/apng/APNGDisassembler.kt index 35f70ecf..c2b482c 100644 --- a/apng_library/src/main/java/oupson/apng/APNGDisassembler.kt +++ b/apng_library/src/main/java/oupson/apng/APNGDisassembler.kt @@ -25,8 +25,8 @@ class APNGDisassembler { private var tnrs: ByteArray? = null private var maxWidth = 0 private var maxHeight = 0 - private var blend_op: Utils.Companion.blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE - private var dispose_op: Utils.Companion.dispose_op = Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE + private var blendOp: Utils.Companion.BlendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE + private var disposeOp: Utils.Companion.DisposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE private var ihdr = IHDR() var apng: Apng = Apng() @@ -98,17 +98,17 @@ class APNGDisassembler { val fcTL = fcTL() fcTL.parse(byteArray) delay = fcTL.delay - yOffset = fcTL.y_offset - xOffset = fcTL.x_offset - blend_op = fcTL.blend_op - dispose_op = fcTL.dispose_op + yOffset = fcTL.yOffset + xOffset = fcTL.xOffset + blendOp = fcTL.blendOp + disposeOp = fcTL.disposeOp val width = fcTL.pngWidth val height = fcTL.pngHeight if (xOffset + width > maxWidth) { - throw BadApng("`y_offset` + `height` must be <= `IHDR` height") + throw BadApng("`yOffset` + `height` must be <= `IHDR` height") } else if (yOffset + height > maxHeight) { - throw BadApng("`y_offset` + `height` must be <= `IHDR` height") + throw BadApng("`yOffset` + `height` must be <= `IHDR` height") } png?.addAll(pngSignature.toList()) @@ -129,15 +129,15 @@ class APNGDisassembler { crC32.update(iend, 0, iend.size) png!!.addAll(iend.toList()) png!!.addAll(to4Bytes(crC32.value.toInt()).toList()) - apng.frames.add(Frame(png!!.toByteArray(), delay, xOffset, yOffset, maxWidth, maxHeight, blend_op, dispose_op)) + apng.frames.add(Frame(png!!.toByteArray(), delay, xOffset, yOffset, maxWidth, maxHeight, blendOp, disposeOp)) png = ArrayList() val fcTL = fcTL() fcTL.parse(byteArray) delay = fcTL.delay - yOffset = fcTL.y_offset - xOffset = fcTL.x_offset - blend_op = fcTL.blend_op - dispose_op = fcTL.dispose_op + yOffset = fcTL.yOffset + xOffset = fcTL.xOffset + blendOp = fcTL.blendOp + disposeOp = fcTL.disposeOp val width = fcTL.pngWidth val height = fcTL.pngHeight png!!.addAll(pngSignature.toList()) @@ -159,7 +159,7 @@ class APNGDisassembler { crC32.update(iend, 0, iend.size) png!!.addAll(iend.toList()) png!!.addAll(to4Bytes(crC32.value.toInt()).toList()) - apng.frames.add(Frame(png!!.toByteArray(), delay, xOffset, yOffset, maxWidth, maxHeight, blend_op, dispose_op)) + apng.frames.add(Frame(png!!.toByteArray(), delay, xOffset, yOffset, maxWidth, maxHeight, blendOp, disposeOp)) } Utils.IDAT -> { if (png == null) { diff --git a/apng_library/src/main/java/oupson/apng/Apng.kt b/apng_library/src/main/java/oupson/apng/Apng.kt index a5b61cb..d6df1d9 100644 --- a/apng_library/src/main/java/oupson/apng/Apng.kt +++ b/apng_library/src/main/java/oupson/apng/Apng.kt @@ -3,14 +3,14 @@ package oupson.apng import android.graphics.Bitmap import android.graphics.BitmapFactory import android.os.Environment -import oupson.apng.ImageUtils.BitmapDiffCalculator -import oupson.apng.ImageUtils.PngEncoder -import oupson.apng.ImageUtils.PnnQuantizer import oupson.apng.chunks.IDAT import oupson.apng.exceptions.NoFrameException +import oupson.apng.imageUtils.BitmapDiffCalculator +import oupson.apng.imageUtils.PngEncoder +import oupson.apng.imageUtils.PnnQuantizer import oupson.apng.utils.Utils -import oupson.apng.utils.Utils.Companion.getBlend_op -import oupson.apng.utils.Utils.Companion.getDispose_op +import oupson.apng.utils.Utils.Companion.getBlendOp +import oupson.apng.utils.Utils.Companion.getDisposeOp import oupson.apng.utils.Utils.Companion.pngSignature import oupson.apng.utils.Utils.Companion.to2Bytes import oupson.apng.utils.Utils.Companion.to4Bytes @@ -21,7 +21,9 @@ import java.util.zip.CRC32 * Create an APNG file */ class Apng { + @Suppress("MemberVisibilityCanBePrivate") var maxWidth : Int? = null + @Suppress("MemberVisibilityCanBePrivate") var maxHeight : Int? = null /** @@ -34,99 +36,29 @@ class Apng { var frames : ArrayList = ArrayList() // region addFrames - /** * Add a frame to the APNG - * @param bitmap The bitamp to add - */ - fun addFrames(bitmap: Bitmap) { - frames.add(Frame(PngEncoder.encode(bitmap, true))) - } - - /** - * Add a frame to the APNG - * @param bitmap The bitamp to add - * @param delay Delay of the frame - */ - fun addFrames(bitmap: Bitmap, delay : Float) { - frames.add(Frame(PngEncoder.encode(bitmap, true), delay)) - } - - /** - * Add a frame to the APNG - * @param bitmap The bitamp to add - * @param delay Delay of the frame - * @param dispose_op `dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). - * @param blend_op `blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. - */ - fun addFrames(bitmap: Bitmap, delay: Float, dispose_op: Utils.Companion.dispose_op, blend_op: Utils.Companion.blend_op) { - frames.add(Frame(PngEncoder.encode(bitmap, true), delay, blend_op, dispose_op)) - } - - /** - * Add a frame to the APNG - * @param bitmap The bitamp to add + * @param bitmap The bitmap to add * @param delay Delay of the frame * @param xOffset The X offset where the frame should be rendered * @param yOffset The Y offset where the frame should be rendered - * @param dispose_op `dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). - * @param blend_op `blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. + * @param disposeOp `DisposeOp` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). + * @param blendOp `BlendOp` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. */ - fun addFrames(bitmap: Bitmap, delay: Float, xOffset : Int, yOffset : Int, dispose_op: Utils.Companion.dispose_op, blend_op: Utils.Companion.blend_op) { - frames.add(Frame(PngEncoder.encode(bitmap, true), delay, xOffset, yOffset, blend_op, dispose_op)) + + fun addFrames(bitmap : Bitmap, index : Int? = null, delay : Float = 1000f, xOffset : Int = 0, yOffset : Int = 0, disposeOp: Utils.Companion.DisposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE, blendOp: Utils.Companion.BlendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE) { + if (index == null) + frames.add(Frame(PngEncoder.encode(bitmap, true), delay, xOffset, yOffset, blendOp, disposeOp)) + else + frames.add(index, Frame(PngEncoder.encode(bitmap, true), delay, xOffset, yOffset, blendOp, disposeOp)) } - /** - * Add a frame to the APNG - * @param index Index where we add the frame - * @param bitmap The bitamp to add - */ - fun addFrames(index : Int, bitmap: Bitmap) { - frames.add(index, Frame(PngEncoder.encode(bitmap, true))) - } - - /** - * Add a frame to the APNG - * @param index Index where we add the frame - * @param bitmap The bitamp to add - * @param delay Delay of the frame - */ - fun addFrames(index : Int, bitmap: Bitmap, delay : Float) { - frames.add(index, Frame(PngEncoder.encode(bitmap, true), delay)) - } - - /** - * Add a frame to the APNG - * @param index Index where we add the frame - * @param bitmap The bitamp to add - * @param delay Delay of the frame - * @param dispose_op `dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). - * @param blend_op `blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. - */ - fun addFrames(index: Int, bitmap: Bitmap, delay: Float, dispose_op: Utils.Companion.dispose_op, blend_op: Utils.Companion.blend_op) { - frames.add(index, Frame(PngEncoder.encode(bitmap, true), delay, blend_op, dispose_op)) - } - - /** - * Add a frame to the APNG - * @param index Index where we add the frame - * @param bitmap The bitamp to add - * @param delay Delay of the frame - * @param xOffset The X offset where the frame should be rendered - * @param yOffset The Y offset where the frame should be rendered - * @param dispose_op `dispose_op` specifies how the output buffer should be changed at the end of the delay (before rendering the next frame). - * @param blend_op `blend_op` specifies whether the frame is to be alpha blended into the current output buffer content, or whether it should completely replace its region in the output buffer. - */ - fun addFrames(index: Int, bitmap: Bitmap, delay: Float, xOffset : Int, yOffset : Int, dispose_op: Utils.Companion.dispose_op, blend_op: Utils.Companion.blend_op) { - frames.add(index, Frame(PngEncoder.encode(bitmap, true), delay, xOffset, yOffset, blend_op, dispose_op)) - } - - fun addFrames(frame : Frame) { - frames.add(frame) - } - - fun addFrames(index: Int,frame : Frame) { - frames.add(index, frame) + @Suppress("unused") + fun addFrames(frame : Frame, index: Int? = null) { + if (index == null) + frames.add(frame) + else + frames.add(index, frame) } //endregion @@ -139,7 +71,6 @@ class Apng { val res = ArrayList() // Add PNG signature res.addAll(pngSignature.toList()) - // Add Image Header res.addAll(generateIhdr().toList()) @@ -178,9 +109,9 @@ class Apng { fcTL.addAll(to2Bytes(frames[0].delay.toInt()).toList()) fcTL.addAll(to2Bytes(1000).toList()) - // Add dispose_op and blend_op - fcTL.add(getDispose_op(frames[0].dispose_op).toByte()) - fcTL.add(getBlend_op(frames[0].blend_op).toByte()) + // Add DisposeOp and BlendOp + fcTL.add(getDisposeOp(frames[0].disposeOp).toByte()) + fcTL.add(getBlendOp(frames[0].blendOp).toByte()) // Create CRC val crc = CRC32() @@ -247,9 +178,9 @@ class Apng { fcTL.addAll(to2Bytes(frames[0].delay.toInt()).toList()) fcTL.addAll(to2Bytes(1000).toList()) - // Add dispose_op and blend_op - fcTL.add(getDispose_op(frames[0].dispose_op).toByte()) - fcTL.add(getBlend_op(frames[0].blend_op).toByte()) + // Add DisposeOp and BlendOp + fcTL.add(getDisposeOp(frames[0].disposeOp).toByte()) + fcTL.add(getBlendOp(frames[0].blendOp).toByte()) // Generate CRC val crc = CRC32() @@ -302,8 +233,8 @@ class Apng { fcTL.addAll(to2Bytes(frames[i].delay.toInt()).toList()) fcTL.addAll(to2Bytes(1000).toList()) - fcTL.add(getDispose_op(frames[i].dispose_op).toByte()) - fcTL.add(getBlend_op(frames[i].blend_op).toByte()) + fcTL.add(getDisposeOp(frames[i].disposeOp).toByte()) + fcTL.add(getBlendOp(frames[i].blendOp).toByte()) val crc = CRC32() crc.update(fcTL.toByteArray(), 0, fcTL.size) @@ -359,6 +290,7 @@ class Apng { * @param maxHeight Max height of the APNG * @return An image cover */ + @Suppress("MemberVisibilityCanBePrivate") fun generateCover(bitmap: Bitmap, maxWidth : Int, maxHeight : Int) : Bitmap { return Bitmap.createScaledBitmap(bitmap, maxWidth, maxHeight, false) } @@ -371,7 +303,7 @@ class Apng { val ihdr = ArrayList() // We need a body var to know body length and generate crc - val ihdr_body = ArrayList() + val ihdrBody = ArrayList() // Get max height and max width of all the frames maxHeight = frames.sortedByDescending { it.height }[0].height @@ -384,20 +316,20 @@ class Apng { // Add chunk body length ihdr.addAll(to4Bytes(frames[0].ihdr.body.size).toList()) // Add IHDR - ihdr_body.addAll(byteArrayOf(0x49.toByte(), 0x48.toByte(), 0x44.toByte(), 0x52.toByte()).toList()) + ihdrBody.addAll(byteArrayOf(0x49.toByte(), 0x48.toByte(), 0x44.toByte(), 0x52.toByte()).toList()) // Add the max width and height - ihdr_body.addAll(to4Bytes(maxWidth!!).toList()) - ihdr_body.addAll(to4Bytes(maxHeight!!).toList()) + ihdrBody.addAll(to4Bytes(maxWidth!!).toList()) + ihdrBody.addAll(to4Bytes(maxHeight!!).toList()) // Add complicated stuff like depth color ... // If you want correct png you need same parameters. Good solution is to create new png. - ihdr_body.addAll(frames[0].ihdr.body.copyOfRange(8, 13).toList()) + ihdrBody.addAll(frames[0].ihdr.body.copyOfRange(8, 13).toList()) // Generate CRC val crC32 = CRC32() - crC32.update(ihdr_body.toByteArray(), 0, ihdr_body.size) - ihdr.addAll(ihdr_body) + crC32.update(ihdrBody.toByteArray(), 0, ihdrBody.size) + ihdr.addAll(ihdrBody) ihdr.addAll(to4Bytes(crC32.value.toInt()).toList()) return ihdr.toByteArray() } @@ -437,12 +369,13 @@ class Apng { * @param keepCover Keep the cover * @param sizePercent Reduce image width/height by percents. */ - fun reduceSize( maxColor : Int, keepCover : Boolean? = null, sizePercent : Int? = null) { + @Suppress("unused") + fun reduceSize(maxColor : Int, keepCover : Boolean? = null, sizePercent : Int? = null) { val apng = Apng() if (keepCover != false) { if (cover != null) { if (sizePercent != null) { - cover = Bitmap.createScaledBitmap(cover, (cover!!.width.toFloat() * sizePercent.toFloat() / 100f).toInt(), (cover!!.height.toFloat() * sizePercent.toFloat() / 100f).toInt(), false) + cover = Bitmap.createScaledBitmap(cover!!, (cover!!.width.toFloat() * sizePercent.toFloat() / 100f).toInt(), (cover!!.height.toFloat() * sizePercent.toFloat() / 100f).toInt(), false) val pnn = PnnQuantizer(cover) cover = pnn.convert(maxColor, false) } @@ -458,9 +391,9 @@ class Apng { val pnn = PnnQuantizer(btm) val btmOptimised = pnn.convert(maxColor, false) if (sizePercent != null) { - apng.addFrames(btmOptimised, it.delay, (it.x_offsets.toFloat() * sizePercent.toFloat() / 100f).toInt(), (it.y_offsets.toFloat() * sizePercent.toFloat() / 100f).toInt(), it.dispose_op, it.blend_op) + apng.addFrames(btmOptimised, 0, it.delay, (it.x_offsets.toFloat() * sizePercent.toFloat() / 100f).toInt(), (it.y_offsets.toFloat() * sizePercent.toFloat() / 100f).toInt(), it.disposeOp, it.blendOp) } else { - apng.addFrames(btmOptimised, it.delay, it.x_offsets, it.y_offsets, it.dispose_op, it.blend_op) + apng.addFrames(btmOptimised, 0, it.delay, it.x_offsets, it.y_offsets, it.disposeOp, it.blendOp) } } frames = apng.frames @@ -481,7 +414,7 @@ class Apng { frames[i].byteArray = PngEncoder.encode(diffCalculator.res, true) frames[i].x_offsets = diffCalculator.xOffset frames[i].y_offsets = diffCalculator.yOffset - frames[i].blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_OVER + frames[i].blendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_OVER } } } \ No newline at end of file diff --git a/apng_library/src/main/java/oupson/apng/ApngAnimator.kt b/apng_library/src/main/java/oupson/apng/ApngAnimator.kt index 23770a6..26b5a84 100644 --- a/apng_library/src/main/java/oupson/apng/ApngAnimator.kt +++ b/apng_library/src/main/java/oupson/apng/ApngAnimator.kt @@ -39,10 +39,12 @@ class ApngAnimator(private val context: Context?) { var anim: CustomAnimationDrawable? = null private var activeAnimation: CustomAnimationDrawable? = null private var doOnLoaded : (ApngAnimator) -> Unit = {} + @Suppress("PrivatePropertyName") @SuppressWarnings("WeakerAccess") private var AnimationLoopListener : () -> Unit = {} private var duration : ArrayList? = null private var scaleType : ImageView.ScaleType? = null + @Suppress("MemberVisibilityCanBePrivate") var isApng = false @SuppressWarnings("WeakerAccess") var loadNotApng = true @@ -56,6 +58,7 @@ class ApngAnimator(private val context: Context?) { /** * Specify if the library could load non apng file */ + @Suppress("unused") @SuppressWarnings("WeakerAccess") fun loadNotApng(boolean: Boolean) { val editor = sharedPreferences?.edit() @@ -78,6 +81,7 @@ class ApngAnimator(private val context: Context?) { * @param speed The speed * @throws NotApngException */ + @Suppress("unused") @SuppressWarnings("WeakerAccess") fun load(file: File, speed: Float? = null, apngAnimatorOptions: ApngAnimatorOptions? = null) : ApngAnimator { doAsync { @@ -230,12 +234,13 @@ class ApngAnimator(private val context: Context?) { } else if (File(string).exists()) { var pathToLoad = if (string.startsWith("content://")) string else "file://$string" pathToLoad = pathToLoad.replace("%", "%25").replace("#", "%23") - val bytes = context!!.contentResolver.openInputStream(Uri.parse(pathToLoad)).readBytes() + val bytes = context?.contentResolver?.openInputStream(Uri.parse(pathToLoad))?.readBytes() + bytes ?: throw Exception("File are empty") if (isApng(bytes)) { load(bytes, speed, apngAnimatorOptions) } else { if (loadNotApng) { - context.runOnUiThread { + context?.runOnUiThread { imageView?.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.size)) } } else { @@ -284,25 +289,25 @@ class ApngAnimator(private val context: Context?) { // Write buffer to canvas canvas.drawBitmap(bitmapBuffer, 0f, 0f, null) // Clear current frame rect - // If `blend_op` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region. - if (it.blend_op == Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE) { - canvas.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + current.width.toFloat(), it.y_offsets!! + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }()) + // If `BlendOp` is APNG_BLEND_OP_SOURCE all color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region. + if (it.blendOp == Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE) { + canvas.drawRect(it.x_offsets.toFloat(), it.y_offsets.toFloat(), it.x_offsets + current.width.toFloat(), it.y_offsets + current.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }()) } // Draw the bitmap - canvas.drawBitmap(current, it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), null) + canvas.drawBitmap(current, it.x_offsets.toFloat(), it.y_offsets.toFloat(), null) generatedFrame.add(btm) // Don't add current frame to bitmap buffer when { - extractedFrame[i].dispose_op == Utils.Companion.dispose_op.APNG_DISPOSE_OP_PREVIOUS -> { + extractedFrame[i].disposeOp == Utils.Companion.DisposeOp.APNG_DISPOSE_OP_PREVIOUS -> { //Do nothings } // Add current frame to bitmap buffer // APNG_DISPOSE_OP_BACKGROUND: the frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame. - it.dispose_op == Utils.Companion.dispose_op.APNG_DISPOSE_OP_BACKGROUND -> { + it.disposeOp == Utils.Companion.DisposeOp.APNG_DISPOSE_OP_BACKGROUND -> { val res = Bitmap.createBitmap(extractedFrame[0].maxWidth!!, extractedFrame[0].maxHeight!!, Bitmap.Config.ARGB_8888) val can = Canvas(res) can.drawBitmap(btm, 0f, 0f, null) - can.drawRect(it.x_offsets!!.toFloat(), it.y_offsets!!.toFloat(), it.x_offsets!! + it.width.toFloat(), it.y_offsets!! + it.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }()) + can.drawRect(it.x_offsets.toFloat(), it.y_offsets.toFloat(), it.x_offsets + it.width.toFloat(), it.y_offsets + it.height.toFloat(), { val paint = Paint(); paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR); paint }()) bitmapBuffer = res } else -> bitmapBuffer = btm diff --git a/apng_library/src/main/java/oupson/apng/Frame.kt b/apng_library/src/main/java/oupson/apng/Frame.kt index 84c1e66..c893121 100644 --- a/apng_library/src/main/java/oupson/apng/Frame.kt +++ b/apng_library/src/main/java/oupson/apng/Frame.kt @@ -37,8 +37,8 @@ class Frame { var maxWidth : Int? = null var maxHeight : Int? = null - var blend_op: Utils.Companion.blend_op - var dispose_op : Utils.Companion.dispose_op + var blendOp: Utils.Companion.BlendOp + var disposeOp : Utils.Companion.DisposeOp constructor(byteArray: ByteArray) { if (isPng(byteArray)) { @@ -46,8 +46,8 @@ class Frame { Log.e("tag", byteArray.size.toString()) // Get width and height for image delay = 1000f - blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE - dispose_op = Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE + blendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE + disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE var cursor = 8 while (cursor < byteArray.size) { val chunk = byteArray.copyOfRange(cursor, cursor + Utils.parseLength(byteArray.copyOfRange(cursor, cursor + 4)) + 12) @@ -70,14 +70,14 @@ class Frame { } this.delay = delay - blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE - dispose_op = Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE + blendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE + disposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE } else { throw NotPngException() } } - constructor(byteArray: ByteArray, delay : Float, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) { + constructor(byteArray: ByteArray, delay : Float, blendOp: Utils.Companion.BlendOp, disposeOp: Utils.Companion.DisposeOp) { if (isPng(byteArray)) { this.byteArray = byteArray // Get width and height for image @@ -93,14 +93,14 @@ class Frame { this.maxWidth = -1 this.maxHeight = -1 - this.blend_op = blend_op - this.dispose_op = dispose_op + this.blendOp = blendOp + this.disposeOp = disposeOp } else { throw NotPngException() } } - constructor(byteArray: ByteArray, delay : Float, xOffsets : Int, yOffsets : Int, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) { + constructor(byteArray: ByteArray, delay : Float, xOffsets : Int, yOffsets : Int, blendOp: Utils.Companion.BlendOp, disposeOp: Utils.Companion.DisposeOp) { if (isPng(byteArray)) { this.byteArray = byteArray // Get width and height for image @@ -118,14 +118,14 @@ class Frame { this.maxWidth = -1 this.maxHeight = -1 - this.blend_op = blend_op - this.dispose_op = dispose_op + this.blendOp = blendOp + this.disposeOp = disposeOp } else { throw NotPngException() } } - constructor(byteArray: ByteArray, delay : Float, xOffsets : Int, yOffsets : Int, maxWidth : Int, maxHeight : Int, blend_op: Utils.Companion.blend_op, dispose_op: Utils.Companion.dispose_op) { + constructor(byteArray: ByteArray, delay : Float, xOffsets : Int, yOffsets : Int, maxWidth : Int, maxHeight : Int, blendOp: Utils.Companion.BlendOp, disposeOp: Utils.Companion.DisposeOp) { if (isPng(byteArray)) { this.byteArray = byteArray // Get width and height for image @@ -143,8 +143,8 @@ class Frame { this.maxWidth = maxWidth this.maxHeight = maxHeight - this.blend_op = blend_op - this.dispose_op = dispose_op + this.blendOp = blendOp + this.disposeOp = disposeOp } else { throw NotPngException() } diff --git a/apng_library/src/main/java/oupson/apng/chunks/IDAT.kt b/apng_library/src/main/java/oupson/apng/chunks/IDAT.kt index 8b33bec..cfd6cf7 100644 --- a/apng_library/src/main/java/oupson/apng/chunks/IDAT.kt +++ b/apng_library/src/main/java/oupson/apng/chunks/IDAT.kt @@ -3,6 +3,7 @@ package oupson.apng.chunks import oupson.apng.utils.Utils.Companion.parseLength class IDAT : Chunk { + @Suppress("PropertyName") var IDATBody: ArrayList = ArrayList() override var body = byteArrayOf() diff --git a/apng_library/src/main/java/oupson/apng/chunks/fcTL.kt b/apng_library/src/main/java/oupson/apng/chunks/fcTL.kt index ed68156..db1962b 100644 --- a/apng_library/src/main/java/oupson/apng/chunks/fcTL.kt +++ b/apng_library/src/main/java/oupson/apng/chunks/fcTL.kt @@ -1,10 +1,11 @@ package oupson.apng.chunks import oupson.apng.utils.Utils -import oupson.apng.utils.Utils.Companion.getBlend_op -import oupson.apng.utils.Utils.Companion.getDispose_op +import oupson.apng.utils.Utils.Companion.getBlendOp +import oupson.apng.utils.Utils.Companion.getDisposeOp import oupson.apng.utils.Utils.Companion.parseLength +@Suppress("ClassName") class fcTL : Chunk { override var body : ByteArray = byteArrayOf() @@ -16,11 +17,11 @@ class fcTL : Chunk { var delay : Float = -1f // x and y offsets - var x_offset : Int = 0 - var y_offset : Int = 0 + var xOffset : Int = 0 + var yOffset : Int = 0 - var blend_op : Utils.Companion.blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_SOURCE - var dispose_op : Utils.Companion.dispose_op = Utils.Companion.dispose_op.APNG_DISPOSE_OP_NONE + var blendOp : Utils.Companion.BlendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_SOURCE + var disposeOp : Utils.Companion.DisposeOp = Utils.Companion.DisposeOp.APNG_DISPOSE_OP_NONE override fun parse(byteArray: ByteArray) { val i = 4 @@ -37,21 +38,21 @@ class fcTL : Chunk { * If the the value of the numerator is 0 the decoder should render the next frame as quickly as possible, though viewers may impose a reasonable lower bound. */ // Get delay numerator - val delay_num = parseLength(byteArray.copyOfRange(i + 24, i + 26)).toFloat() + val delayNum = parseLength(byteArray.copyOfRange(i + 24, i + 26)).toFloat() // Get delay denominator - var delay_den = parseLength(byteArray.copyOfRange(i + 26, i + 28)).toFloat() + var delayDen = parseLength(byteArray.copyOfRange(i + 26, i + 28)).toFloat() // If the denominator is 0, it is to be treated as if it were 100 (that is, `delay_num` then specifies 1/100ths of a second). - if (delay_den == 0f) { - delay_den = 100f + if (delayDen == 0f) { + delayDen = 100f } - delay = (delay_num / delay_den * 1000) + delay = (delayNum / delayDen * 1000) // Get x and y offsets - x_offset = parseLength(byteArray.copyOfRange(i + 16, i + 20)) - y_offset = parseLength(byteArray.copyOfRange(i + 20, i + 24)) + xOffset = parseLength(byteArray.copyOfRange(i + 16, i + 20)) + yOffset = parseLength(byteArray.copyOfRange(i + 20, i + 24)) body = byteArray.copyOfRange(i + 4, i + bodySize + 4) - blend_op = getBlend_op(String.format("%02x", byteArray[33]).toLong(16).toInt()) - dispose_op = getDispose_op(String.format("%02x", byteArray[32]).toLong(16).toInt()) + blendOp = getBlendOp(String.format("%02x", byteArray[33]).toLong(16).toInt()) + disposeOp = getDisposeOp(String.format("%02x", byteArray[32]).toLong(16).toInt()) } } } \ No newline at end of file diff --git a/apng_library/src/main/java/oupson/apng/ImageUtils/BitmapDiffCalculator.kt b/apng_library/src/main/java/oupson/apng/imageUtils/BitmapDiffCalculator.kt similarity index 96% rename from apng_library/src/main/java/oupson/apng/ImageUtils/BitmapDiffCalculator.kt rename to apng_library/src/main/java/oupson/apng/imageUtils/BitmapDiffCalculator.kt index ed98464..850e21a 100644 --- a/apng_library/src/main/java/oupson/apng/ImageUtils/BitmapDiffCalculator.kt +++ b/apng_library/src/main/java/oupson/apng/imageUtils/BitmapDiffCalculator.kt @@ -1,10 +1,10 @@ -package oupson.apng.ImageUtils +package oupson.apng.imageUtils import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint -import android.support.annotation.ColorInt +import androidx.annotation.ColorInt import oupson.apng.utils.Utils import java.util.* @@ -12,7 +12,7 @@ class BitmapDiffCalculator(firstBitmap: Bitmap, secondBitmap : Bitmap) { val res : Bitmap var xOffset : Int = 0 var yOffset : Int = 0 - var blend_op = Utils.Companion.blend_op.APNG_BLEND_OP_OVER + var blendOp = Utils.Companion.BlendOp.APNG_BLEND_OP_OVER init { val difBitmap = Bitmap.createBitmap(firstBitmap.width, firstBitmap.height, Bitmap.Config.ARGB_8888) val difCanvas = Canvas(difBitmap) diff --git a/apng_library/src/main/java/oupson/apng/ImageUtils/PngEncoder.kt b/apng_library/src/main/java/oupson/apng/imageUtils/PngEncoder.kt similarity index 99% rename from apng_library/src/main/java/oupson/apng/ImageUtils/PngEncoder.kt rename to apng_library/src/main/java/oupson/apng/imageUtils/PngEncoder.kt index b3526c6..aaa75d1 100644 --- a/apng_library/src/main/java/oupson/apng/ImageUtils/PngEncoder.kt +++ b/apng_library/src/main/java/oupson/apng/imageUtils/PngEncoder.kt @@ -1,4 +1,4 @@ -package oupson.apng.ImageUtils +package oupson.apng.imageUtils import android.graphics.Bitmap import java.io.ByteArrayOutputStream @@ -182,6 +182,7 @@ class PngEncoder { * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ + @Suppress("unused") private fun writeInt2(n: Int, offset: Int): Int { val temp = byteArrayOf((n shr 8 and 0xff).toByte(), (n and 0xff).toByte()) return writeBytes(temp, offset) diff --git a/apng_library/src/main/java/oupson/apng/ImageUtils/PnnQuantizer.java b/apng_library/src/main/java/oupson/apng/imageUtils/PnnQuantizer.java similarity index 99% rename from apng_library/src/main/java/oupson/apng/ImageUtils/PnnQuantizer.java rename to apng_library/src/main/java/oupson/apng/imageUtils/PnnQuantizer.java index 56fcd47..17888f6 100644 --- a/apng_library/src/main/java/oupson/apng/ImageUtils/PnnQuantizer.java +++ b/apng_library/src/main/java/oupson/apng/imageUtils/PnnQuantizer.java @@ -1,4 +1,4 @@ -package oupson.apng.ImageUtils; +package oupson.apng.imageUtils; /* Fast pairwise nearest neighbor based algorithm for multilevel thresholding Copyright (C) 2004-2016 Mark Tyler and Dmitry Groshev diff --git a/apng_library/src/main/java/oupson/apng/utils/Utils.kt b/apng_library/src/main/java/oupson/apng/utils/Utils.kt index ab62432..01d046d 100644 --- a/apng_library/src/main/java/oupson/apng/utils/Utils.kt +++ b/apng_library/src/main/java/oupson/apng/utils/Utils.kt @@ -19,7 +19,7 @@ class Utils { if (!isPng(byteArray)) return false try { val acTL = byteArrayOf(0x61, 0x63, 0x54, 0x4c) - val IDAT = byteArrayOf(0x49, 0x44, 0x41, 0x54) + @Suppress("LocalVariableName") val IDAT = byteArrayOf(0x49, 0x44, 0x41, 0x54) for (i in 0 until byteArray.size) { val it = byteArray.copyOfRange(i, i + 4) // if byteArray contain acTL @@ -40,66 +40,66 @@ class Utils { */ val pngSignature: ByteArray = byteArrayOf(0x89.toByte(), 0x50.toByte(), 0x4E.toByte(), 0x47.toByte(), 0x0D.toByte(), 0x0A.toByte(), 0x1A.toByte(), 0x0A.toByte()) - enum class dispose_op { + enum class DisposeOp { APNG_DISPOSE_OP_NONE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS } /** - * Get the int equivalent to the dispose_op - * @param dispose_op The dispose_op - * @return An int equivalent to the dispose_op + * Get the int equivalent to the DisposeOp + * @param disposeOp The DisposeOp + * @return An int equivalent to the DisposeOp */ - fun getDispose_op(dispose_op: dispose_op) : Int { - return when(dispose_op) { - Companion.dispose_op.APNG_DISPOSE_OP_NONE -> 0 - Companion.dispose_op.APNG_DISPOSE_OP_BACKGROUND -> 1 - Companion.dispose_op.APNG_DISPOSE_OP_PREVIOUS -> 2 + fun getDisposeOp(disposeOp: DisposeOp) : Int { + return when(disposeOp) { + Companion.DisposeOp.APNG_DISPOSE_OP_NONE -> 0 + Companion.DisposeOp.APNG_DISPOSE_OP_BACKGROUND -> 1 + Companion.DisposeOp.APNG_DISPOSE_OP_PREVIOUS -> 2 } } /** - * Get the dispose_op enum equivalent to the int - * @param int Int of the dispose_op - * @return A dispose_op + * Get the DisposeOp enum equivalent to the int + * @param int Int of the DisposeOp + * @return A DisposeOp */ - fun getDispose_op(int: Int) : dispose_op { + fun getDisposeOp(int: Int) : DisposeOp { return when(int) { - 0 -> dispose_op.APNG_DISPOSE_OP_NONE - 1 -> dispose_op.APNG_DISPOSE_OP_BACKGROUND - 2 -> dispose_op.APNG_DISPOSE_OP_PREVIOUS - else -> dispose_op.APNG_DISPOSE_OP_NONE + 0 -> DisposeOp.APNG_DISPOSE_OP_NONE + 1 -> DisposeOp.APNG_DISPOSE_OP_BACKGROUND + 2 -> DisposeOp.APNG_DISPOSE_OP_PREVIOUS + else -> DisposeOp.APNG_DISPOSE_OP_NONE } } - enum class blend_op() { + enum class BlendOp { APNG_BLEND_OP_SOURCE, APNG_BLEND_OP_OVER } /** - * Get the int equivalent to the blend_op - * @param blend_op The blend_op - * @return An int equivalent to the blend_op + * Get the int equivalent to the BlendOp + * @param blendOp The BlendOp + * @return An int equivalent to the BlendOp */ - fun getBlend_op(blend_op: blend_op) : Int { - return when(blend_op) { - Companion.blend_op.APNG_BLEND_OP_SOURCE -> 0 - Companion.blend_op.APNG_BLEND_OP_OVER -> 1 + fun getBlendOp(blendOp: BlendOp) : Int { + return when(blendOp) { + Companion.BlendOp.APNG_BLEND_OP_SOURCE -> 0 + Companion.BlendOp.APNG_BLEND_OP_OVER -> 1 } } /** - * Get the blend_op enum equivalent to the int - * @param int Int of the blend_op - * @return A blend_op + * Get the BlendOp enum equivalent to the int + * @param int Int of the BlendOp + * @return A BlendOp */ - fun getBlend_op(int : Int) : blend_op { + fun getBlendOp(int : Int) : BlendOp { return when(int) { - 0 -> blend_op.APNG_BLEND_OP_SOURCE - 1 -> blend_op.APNG_BLEND_OP_OVER - else -> blend_op.APNG_BLEND_OP_SOURCE + 0 -> BlendOp.APNG_BLEND_OP_SOURCE + 1 -> BlendOp.APNG_BLEND_OP_OVER + else -> BlendOp.APNG_BLEND_OP_SOURCE } } @@ -137,12 +137,12 @@ class Utils { return lengthString.toLong(16).toInt() } - val fcTL = Arrays.toString(byteArrayOf(0x66, 0x63, 0x54, 0x4c)) - val IEND = Arrays.toString(byteArrayOf(0x49, 0x45, 0x4e, 0x44)) - val IDAT = Arrays.toString(byteArrayOf(0x49, 0x44, 0x41, 0x54)) - val fdAT = Arrays.toString(byteArrayOf(0x66, 0x64, 0x41, 0x54)) - val plte = Arrays.toString(byteArrayOf(0x50, 0x4c, 0x54, 0x45)) - val tnrs = Arrays.toString(byteArrayOf(0x74, 0x52, 0x4e, 0x53)) - val IHDR = Arrays.toString(byteArrayOf(0x49, 0x48, 0x44, 0x52)) + val fcTL : String = Arrays.toString(byteArrayOf(0x66, 0x63, 0x54, 0x4c)) + val IEND : String = Arrays.toString(byteArrayOf(0x49, 0x45, 0x4e, 0x44)) + val IDAT : String = Arrays.toString(byteArrayOf(0x49, 0x44, 0x41, 0x54)) + val fdAT : String = Arrays.toString(byteArrayOf(0x66, 0x64, 0x41, 0x54)) + val plte : String = Arrays.toString(byteArrayOf(0x50, 0x4c, 0x54, 0x45)) + val tnrs : String = Arrays.toString(byteArrayOf(0x74, 0x52, 0x4e, 0x53)) + val IHDR : String = Arrays.toString(byteArrayOf(0x49, 0x48, 0x44, 0x52)) } } \ No newline at end of file diff --git a/app-test/build.gradle b/app-test/build.gradle index c51d110..1784ea4 100644 --- a/app-test/build.gradle +++ b/app-test/build.gradle @@ -12,7 +12,7 @@ android { targetSdkVersion 28 versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } // Configure only for each module that uses Java 8 // language features (either in its source code or @@ -35,17 +35,17 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" //noinspection GradleCompatible - implementation 'com.android.support:appcompat-v7:27.1.1' - implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' implementation "org.jetbrains.anko:anko:$anko_version" implementation 'com.squareup.picasso:picasso:2.71828' implementation project(":apng_library") // implementation fileTree(include: ['*.aar'], dir: 'libs') //implementation 'com.github.oupson:Kapng-Android:1.0.0' - implementation 'com.android.support:design:27.1.1' // where X.X.X version + implementation 'com.google.android.material:material:1.0.0' // where X.X.X version implementation "org.jetbrains.anko:anko-appcompat-v7:$anko_version" implementation "org.jetbrains.anko:anko-design:$anko_version" implementation "org.jetbrains.anko:anko-constraint-layout:$anko_version" diff --git a/app-test/src/androidTest/java/oupson/apngcreator/ExampleInstrumentedTest.kt b/app-test/src/androidTest/java/oupson/apngcreator/ExampleInstrumentedTest.kt index 2d70ec6..ae350dd 100644 --- a/app-test/src/androidTest/java/oupson/apngcreator/ExampleInstrumentedTest.kt +++ b/app-test/src/androidTest/java/oupson/apngcreator/ExampleInstrumentedTest.kt @@ -1,7 +1,7 @@ package oupson.apngcreator -import android.support.test.InstrumentationRegistry -import android.support.test.runner.AndroidJUnit4 +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith diff --git a/app-test/src/main/java/oupson/apngcreator/CreatorActivity.kt b/app-test/src/main/java/oupson/apngcreator/CreatorActivity.kt index 73c441c..37e840a 100644 --- a/app-test/src/main/java/oupson/apngcreator/CreatorActivity.kt +++ b/app-test/src/main/java/oupson/apngcreator/CreatorActivity.kt @@ -8,11 +8,11 @@ import android.graphics.BitmapFactory import android.graphics.Color import android.os.Bundle import android.os.Environment -import android.support.design.widget.FloatingActionButton -import android.support.v7.app.AppCompatActivity import android.text.Html import android.view.View import android.widget.ListView +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.floatingactionbutton.FloatingActionButton import org.jetbrains.anko.* import org.jetbrains.anko.design.appBarLayout import org.jetbrains.anko.design.floatingActionButton diff --git a/app-test/src/main/java/oupson/apngcreator/Main2Activity.kt b/app-test/src/main/java/oupson/apngcreator/Main2Activity.kt index a00d3c8..513db95 100644 --- a/app-test/src/main/java/oupson/apngcreator/Main2Activity.kt +++ b/app-test/src/main/java/oupson/apngcreator/Main2Activity.kt @@ -4,11 +4,11 @@ import android.Manifest import android.content.pm.PackageManager import android.graphics.Color import android.os.Bundle -import android.support.v4.app.ActivityCompat -import android.support.v4.content.ContextCompat -import android.support.v7.app.AppCompatActivity import android.view.View import android.widget.ImageView +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat import org.jetbrains.anko.backgroundColor import org.jetbrains.anko.imageView import org.jetbrains.anko.matchParent diff --git a/app-test/src/main/java/oupson/apngcreator/MainActivity.kt b/app-test/src/main/java/oupson/apngcreator/MainActivity.kt index 3806231..08e978a 100644 --- a/app-test/src/main/java/oupson/apngcreator/MainActivity.kt +++ b/app-test/src/main/java/oupson/apngcreator/MainActivity.kt @@ -3,12 +3,12 @@ package oupson.apngcreator import android.graphics.Color import android.graphics.drawable.GradientDrawable import android.os.Bundle -import android.support.constraint.ConstraintLayout -import android.support.v7.app.AppCompatActivity import android.text.Html import android.util.Log import android.view.View import android.widget.Toolbar +import androidx.appcompat.app.AppCompatActivity +import androidx.constraintlayout.widget.ConstraintLayout import com.squareup.picasso.Picasso import org.jetbrains.anko.* import org.jetbrains.anko.constraint.layout.ConstraintSetBuilder diff --git a/gradle.properties b/gradle.properties index b2b3bb2..16508a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,8 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. +android.enableJetifier=true +android.useAndroidX=true org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit