Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

优化 APNG 支持 #4230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
Glavo wants to merge 17 commits into HMCL-dev:main
base: main
Choose a base branch
Loading
from Glavo:apng
Draft

优化 APNG 支持 #4230

Glavo wants to merge 17 commits into HMCL-dev:main from Glavo:apng

Conversation

@Glavo
Copy link
Member

@Glavo Glavo commented Aug 9, 2025

目前还无法工作,待修复。

@Glavo Glavo requested a review from Copilot August 9, 2025 13:15
Copilot

This comment was marked as outdated.

Glavo and others added 6 commits August 14, 2025 21:04
...eCanvas.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
...eCanvas.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
...eCanvas.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
...eCanvas.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
...eAnimationImage.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
...eCanvas.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Glavo Glavo requested a review from Copilot August 14, 2025 13:18
Copilot

This comment was marked as outdated.

@Glavo Glavo requested a review from Copilot August 14, 2025 13:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the APNG (Animated PNG) support system to optimize image handling for animated images. The changes replace the old interface-based animation system with a new class-based approach and introduce specialized BGRA pre-multiplied pixel handling for better animation performance.

Key changes:

  • Converts AnimationImage from interface to abstract class with built-in animation timeline management
  • Introduces new BGRA pre-multiplied pixel format classes for more efficient animation frame handling
  • Replaces the old APNG processing logic in ImageUtils with a new director-based approach

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
AnimationImage.java Converted from interface to abstract class with animation timeline management
AnimationFrame.java New interface defining animation frame duration contract
BgraPreCanvas.java New canvas class for BGRA pre-multiplied pixel operations
BgraPreFrame.java New animation frame implementation extending BgraPreCanvas
BgraPreAnimationImage.java New animation image implementation using BGRA pre-multiplied format
AnimationImageImpl.java Refactored to extend new AnimationImage base class
BgraPreBitmapDirector.java New director class for processing APNG files into BGRA format
Argb8888Director.java Added exception handling to receiveFrameImage method
ImageUtils.java Simplified APNG loading by replacing complex logic with director pattern

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

import java.util.Arrays;
import java.util.Objects;

public class BgraPreCanvas {
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argbToPre method lacks documentation explaining what 'pre' means and the purpose of the alpha premultiplication calculation.

Suggested change
public class BgraPreCanvas {
public class BgraPreCanvas {
/**
* Converts an ARGB color value to its premultiplied alpha ("pre") form.
* <p>
* In premultiplied alpha format, the red, green, and blue color components are
* each multiplied by the alpha component and divided by 255. This is commonly
* used in image compositing to simplify blending calculations and improve performance.
* <p>
* For example, if the original color is (A, R, G, B), the premultiplied color is
* (A, R * A / 255, G * A / 255, B * A / 255).
*
* @param argb the original ARGB color value (with 8 bits per channel)
* @return the color value in premultiplied alpha format
*/

Copilot uses AI. Check for mistakes.
ByteArray.setIntLE(pixels, targetIndex, resultArgbPre);
}
}
}
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toString() method override simply calls super.toString() without adding any value. This override should either provide meaningful information about the canvas state or be removed.

Copilot uses AI. Check for mistakes.
@Override
public Argb8888ScanlineProcessor receiveFrameControl(PngFrameControl control) {
//throw new IllegalStateException("TODO up to here");
//return null;
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code should be removed. These TODO comments and dead code lines make the codebase harder to maintain.

Suggested change
//return null;

Copilot uses AI. Check for mistakes.
//return null;
currentFrame = control;

//System.out.println("Frame: "+control);
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statement should be removed from production code.

Suggested change
//System.out.println("Frame: "+control);

Copilot uses AI. Check for mistakes.

@Override
public void receiveDefaultImage(Argb8888Bitmap bitmap) {
// this.bitmapSequence.receiveDefaultImage(bitmap);
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code should be removed to keep the codebase clean.

Suggested change
// this.bitmapSequence.receiveDefaultImage(bitmap);

Copilot uses AI. Check for mistakes.

//System.out.println("Frame: "+control);

return scanlineProcessor.cloneWithNewBitmap(header.adjustFor(control)); // TODO: is this going to be a problem?
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO comment indicates uncertainty about potential issues. This should be investigated and resolved or properly documented if the concern is valid.

Suggested change
returnscanlineProcessor.cloneWithNewBitmap(header.adjustFor(control)); // TODO: is this going to be a problem?
// It is safe to clone the scanline processor with a new bitmap for each frame,
// as cloneWithNewBitmap creates an independent processor instance for the frame's region.
return scanlineProcessor.cloneWithNewBitmap(header.adjustFor(control));

Copilot uses AI. Check for mistakes.
@Override
public Image getResult() {
if (doScale) {
throw new UnsupportedOperationException("TODO"); // TODO
Copy link

Copilot AI Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scaling functionality is not implemented but the method can be called when doScale is true. This will cause runtime failures when users request scaled images.

Suggested change
thrownewUnsupportedOperationException("TODO"); // TODO
// Scale each frame to the target size
List<BgraPreFrame> scaledFrames = new ArrayList<>(animationFrames.size());
for (BgraPreFrame frame : animationFrames) {
scaledFrames.add(scaleFrame(frame, targetWidth, targetHeight));
}
int cycleCount;
if (animationControl != null) {
cycleCount = animationControl.numPlays;
if (cycleCount == 0)
cycleCount = Timeline.INDEFINITE;
} else
cycleCount = Timeline.INDEFINITE;
return new BgraPreAnimationImage(targetWidth, targetHeight, cycleCount, List.copyOf(scaledFrames));

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot Copilot left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /