-
Notifications
You must be signed in to change notification settings - Fork 24
feat: add support for apng #48
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
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #48 +/- ##
==========================================
+ Coverage 89.62% 92.53% +2.90%
==========================================
Files 12 12
Lines 945 1219 +274
Branches 187 252 +65
==========================================
+ Hits 847 1128 +281
+ Misses 98 91 -7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
fe40263
to
499ffe9
Compare
The blend_op image was taken from here. https://philip.html5.org/tests/apng/tests.html#apng-blend-op-over-on-solid-and-transparent-colours Unlike regular png images I couldn't find/make 16bit or interlaced apng images. 16 bits are supposed to work because the data decoding uses same functions as for a regular png 16 bit image. Interlaced one, I am not even sure if it needs to be added. On one side the specification doesn't say that apng image can't be interlaced. But on the other side the idea of interlaced apng image is weird and i can't find any examples for it. Should I just drop it and leave it for non-interlaced frames? |
It is not practical to have a method that can return different types depending on the input data. Before refactoring, can you suggest typings something that:
|
If we can't find an example interlaced APNG, we can drop it for now. |
Then I guess I shouldn't overcomplicate things. Like you said I can just add a separate public decodeApng(): DecodedPng[] {
checkSignature(this);
while (!this._end) {
this.decodeChunk();
}
const result = this.decodeApngImage();
return result;
} The issue, however, is with trying to decode a regular PNG as APNG. If we want to skip other frames for regular png instead of decoding them, then we need to create another function like |
Yes, that sounds ok. I don't know if it's doable but Still, can you suggest a different return type for the |
If I understand you correctly, then I think we can keep the initial DecodedPng type for that. The frames can be stored in a separate field. export interface DecodedPng {
width: number;
height: number;
data: PngDataArray;
depth: BitDepth;
channels: number;
text: Record<string, string>;
resolution?: PngResolution;
palette?: IndexedColors;
transparency?: Uint16Array;
iccEmbeddedProfile?: IccEmbeddedProfile;
frames?: DecodedPngFrame[];
} The idea was to read the apng frame by frame and- since APNG can store only a part of the frame that actually changes -I wanted to create an array of ready-to-be-encoded PNG images. Even if the frame's data gets decoded as it is, it might not hold much value, because it might not contain the whole image, and its metadata serves to kind of "put the changed data" on the main canvas(1st frame). Thus is the question, how should the decoded frames look like? |
For the reference here is what a frame looks like: export interface DecodedPngFrame {
sequenceNumber: number;
width: number;
height: number;
xOffset: number;
yOffset: number;
delayNumber: number;
delayDenominator: number;
disposeOp: number;
blendOp: number;
data: Uint8Array;
} Perhaps we can add another function called |
The frames should be returned decoded. I feel like you are confusing what the PNGDecoder class returns with what the |
So, the idea is to have something like this? interface DecodedPng{
width: number;
height: number;
data: PngDataArray;
depth: BitDepth;
channels: number;
text: Record<string, string>;
resolution?: PngResolution;
palette?: IndexedColors;
transparency?: Uint16Array;
iccEmbeddedProfile?: IccEmbeddedProfile;
frames?: PngDataArray[]; // Stores the decoded data for each frame
} |
Not exactly:
|
Yeah, fair enough. If we make a separate function for it, there is no need for a common data type. Then we can make something like this: interface DecodedApng{
width: number;
height: number;
depth: BitDepth;
channels: number;
numberOfFrames:number;
numberOfReps:number;
resolution?: PngResolution;
text: Record<string, string>;
palette?: IndexedColors;
transparency?: Uint16Array;
iccEmbeddedProfile?: IccEmbeddedProfile;
frames: Array<{
sequenceNumber: number;
delayNumber: number;
delayDenominator: number;
data: Uint8Array;
}>
} Frames objects will have their own type obviously. |
No description provided.