Trimmed Video Luminosity / Most Significant Bits issue
I think there is an unsigned integer wraparound, perhaps because the trimmed video attempts more than just straightening the curved spectral lines. The burnt out pixels look like still contain information, but with the most significant bit having gone missing, ie modulo / wraparound.
Top: original input Bottom: trimmed video with burnt out pixels
Below, the most significant bit suspicion when a sunspot darkens the light going into the slit
A similar effect can be achieved if I artificially decrease the bit depth when viewing the ser
Does JSol'Ex open the trimmed file correctly? e.g in the player? SER recorders like Sharpcap "lie" about the pixel depth, which forces readers like SER Player or even JSol'Ex to infer the pixel depth.
I'd say it is royally beyond repair, both the original and the trimmed
Alright. I thought I fixed all these nasty bugs. I guess you don't have the original at hand anymore?
I ran one of the ser files through PIPP, just ser output, no processing/triming/cropping/debayring, nothing,
to see what happens if I try to load that into JSolEx,
same file
I do have the original, I am drowning in dozens of terabytes of unprocessed raw ser videos, it is rather excruciating actually, the pressure to decide what to keep, for how long, and what to delete, and when would have that deleted file come in handy
narnia link coming
http://narnia.go.ro/seagate2tb.php?mask=2025-05-01
I noticed this is a recurring issue, this is in 3.2.1. At around small gain values and millisecond exposures. The original ser video is not saturated
This problem still persists in 3.2.2, the video is recorded at about 10ms, with gain 0, saturation kept at 70-80% max (worse when reaching 90%)
The problem present in 3.3.1 also.
Correct, I haven't figured that out yet.
I found this in your code
https://github.com/melix/astro4j/blob/main/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L180C13-L180C68
I thought maybe there is something weird in my files, wrote some code to dump what's in the .ser files' header -- nothing stands out:
Here's a working instance (which saturates pixels that are saturated in the original, H alpha, don't care about the context)
{
"1_FileID": "LUCAM-RECORDER",
"2_LuID": "4\\0x12\\0x00\\0x00",
"3_ColorID": 0,
"4_LittleEndian": 0,
"5_ImageWidth": 3200,
"6_ImageHeight": 180,
"7_PixelDepthPerPlane": 16,
"8_FrameCount": 10874,
"9_Observer": "Observer ",
"10_Instrument": "ZWO ASI678MM ",
"11_Telescope": "Telescope ",
"12_DateTime": "Tue, 08 Jul 2025 13:30:43 +0200",
"13_DateTime_UTC": "Tue, 08 Jul 2025 10:30:43 +0200",
"frameSize_Bytes": 1152000,
"imageDataSize_Bytes": 12526848000,
"headerSize_Bytes": 178,
"filesize_Bytes": 12526935170,
"tailsize_Bytes": 86992,
"tailsizePerFrame_Bytes": 8
}
and the input file's header that generates the lost bits output
{
"1_FileID": "LUCAM-RECORDER",
"2_LuID": "4\\0x12\\0x00\\0x00",
"3_ColorID": 0,
"4_LittleEndian": 0,
"5_ImageWidth": 3400,
"6_ImageHeight": 800,
"7_PixelDepthPerPlane": 16,
"8_FrameCount": 986,
"9_Observer": "Observer ",
"10_Instrument": "ZWO ASI678MM ",
"11_Telescope": "Telescope ",
"12_DateTime": "Tue, 08 Jul 2025 11:53:23 +0200",
"13_DateTime_UTC": "Tue, 08 Jul 2025 08:53:23 +0200",
"frameSize_Bytes": 5440000,
"imageDataSize_Bytes": 5363840000,
"headerSize_Bytes": 178,
"filesize_Bytes": 5363848066,
"tailsize_Bytes": 7888,
"tailsizePerFrame_Bytes": 8
}
Could you please double check the meaning of this line:
https://github.com/melix/astro4j/blob/main/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L230
it seems to me that you are dropping significant bits (shifting to the left 8+bits to drop) instead of to the right
frameData.getShort() returns a int16_t, signed. I think the culprit is somewhere over there
No it's not. The reader is not a fault, it has been tested intensively. If there's an issue, it's with the writer. See the spec at https://grischa-hahn.hier-im-netz.de/astro/ser/
What do you mean by "the writer" -- the way you output these frames, either to the trimmed video and/or fits frames? Or sharpcap? AS4, PIPP etc read these files well.
My C mind really wants to put that getShort into a proper local variable and make sure all the bits are accounted for, and the most significant bit is not somehow shifted into oblivion because reasons, integer promotion or whatnot
The code you're looking at is the code which infers the pixel depth, not the code which will decode the bytes (that's why you are in fixReader). It's there to do the same as other SER readers like SER Player do, which is because some software lie on the pixel depth. Decoding happens in decoders like https://github.com/melix/astro4j/blob/518c3ceb844991ec78b3cdb17cd7b6094c96d3f8/jsolex-core/src/main/java/me/champeau/a4j/jsolex/processing/ser/FastImageConverter.java#L95
I'm mentioning the writer because you're saying you have the problem on a trimmed file, and the trimmed file is using a writer of mine, so it has more chances of being faulty, since it's not as intensively tested.
https://github.com/melix/astro4j/blob/e7f8654ab814d9a39d46e9982791cbdac8c809e2/jserfile/src/main/java/me/champeau/a4j/ser/SerFileWriter.java#L34
We've established the problem is also
- in the frame debugger
- in the img(nnn) output
The same in AS4
IMHO, this symptom is definitely that of losing bits, it could well be the sign bit getting lost somewhere for whatever reason
Your viewer is also a bit (one bit?) brighter, compared to AS4's raw view
To better explain what I am talking about, please consider this naive snippet I quickly hacked togehter, where I make one bit get lost, because integer promotion etc moves the sign bit around before shifting:
Wait, I thought you told me you had the same issue replaying the trimmed video in SER player. What does the log say wrt to number of bits? Again this could simply be bad sampling, we have to infer the pixel depth...
The trimmed video reflects this issue, but it begins earlier then the trimming. It is there from the very start, I have an idea, let me check it
Ok I had misunderstood. Then my educated guess is that it inferred 15 bits instead of 16 in your case (that shows up in the logs as a line like:
Color mode : MONO (2 bytes per pixel, depth = 16 bits)
OK, so you have two different methods to get the same color:
One is here: https://github.com/melix/astro4j/blob/518c3ceb844991ec78b3cdb17cd7b6094c96d3f8/jsolex-core/src/main/java/me/champeau/a4j/jsolex/processing/ser/FastImageConverter.java#L91
And the other one is here https://github.com/melix/astro4j/blob/edac445e0eaa7257be6f15f50770f952db4e411a/jserfile/src/main/java/me/champeau/a4j/ser/SerFileReader.java#L223
Am I missing something?
Please look at not a few bits but a byte going missing,
am I missing somehitng?
Yes. Inference :) (and the fact there are different decoders, so there's more than 2 versions to read a color, since it also depends on whether it's mono, bayer, ... :D). Welcome to the wonderful world of codecs :)
fucketyfuck, it was there in the log all along
depth = 15 bits
12:06:19.166 [INFO] Output directory set to D:\2025-07-08\Sun-3640_filter-n99--Skywatcher-OtaR62Ap400F-SHG
12:06:19.166 [INFO] File 2025-07-08-0847_0-Sun-3640.ser
12:06:19.230 [INFO] Date 2025-07-08T08:46:44.632850600
12:06:19.231 [INFO] SER file contains 945 frames
12:06:19.231 [INFO] Color mode : MONO (2 bytes per pixel, depth = 15 bits)
12:06:19.231 [INFO] Width: 3400, height: 800
12:06:19.231 [INFO] Solar parameters Carrington rotation = 2299, B0 = 3.66°, L0 = 110.48°, P = 0.74°
12:06:19.231 [INFO] Computing average image and detecting limb
12:06:44.107 [INFO] Dimensions of raw image determined : 3400x945
12:06:44.108 [INFO] Processing will require approximatively 275.77MB of disk space
12:06:45.623 [INFO] Detected spectral line Sodium (D1) (5895.92Å) with binning 1 (for pixel size 2.00µm)
12:06:45.623 [INFO] Starting reconstruction...
12:06:45.623 [INFO] Distortion polynomial ax3 + bx2 + cx + d = 0
- a = 0.0
- b = 7.033106896505656E-6
- c = 0.0013451866444161695
- d = 221.69989718673153
12:06:45.623 [INFO] Memory pressure factor 3
12:06:45.623 [INFO] Processing batch 1
12:06:53.730 [INFO] Reconstruction performance: 613.2 MB/s
12:06:53.830 [INFO] Global reconstruction performance: 597.4 MB/s
12:06:53.830 [INFO] Reconstruction done. Generating images...
12:06:59.219 [INFO] Black estimate 356.08
12:06:59.307 [INFO] Detected X/Y ratio: 0.16
12:06:59.965 [INFO] Diameter 2931.20
12:07:03.122 [INFO] Dimensions of geometry corrected image determined : 4400x4400
So, the reader picks up a random number of frames, some at the beginning, some at the middle, etc to figure out the max value and pixel depth. Let me guess, in your video, you have very large black regions?
Anyway, my intuition is that the sign bit, in some type inference, integer promotion, goes missing
Another idea: why do you go
var dataLen = width * height * numPlanes;
for (int j = 0; j < dataLen; j += 16) {
why do you jump by 16 here? You'd not process the entire frame
because we want the inference to not slow down processing too much. This is already the reason why when you select a large file it takes sometimes several seconds before showing that it's going to process it.