/// <summary> /// parse an PDS packet which contain palette info /// </summary> /// <param name="buffer">Buffer of raw byte data, starting right after segment</param> /// <param name="segment">object containing info about the current segment</param> /// <param name="pic">SubPicture object containing info about the current caption</param> /// <param name="msg">reference to message string</param> /// <returns>number of valid palette entries (-1 for fault)</returns> private static int ParsePds(byte[] buffer, SupSegment segment, BluRaySupPicture pic, string[] msg) { int paletteId = buffer[0]; // 8bit palette ID (0..7) // 8bit palette version number (incremented for each palette change) int paletteUpdate = buffer[1]; if (pic.Palettes == null) { pic.Palettes = new List <List <PaletteInfo> >(); for (int i = 0; i < 8; i++) { pic.Palettes.Add(new List <PaletteInfo>()); } } if (paletteId > 7) { msg[0] = "Illegal palette id at offset " + ToolBox.ToHex(buffer, 0, 8); return(-1); } List <PaletteInfo> al = pic.Palettes[paletteId]; if (al == null) { al = new List <PaletteInfo>(); } PaletteInfo p = new PaletteInfo(); p.PaletteSize = (segment.Size - 2) / 5; p.PaletteBuffer = new byte[p.PaletteSize * 5]; Buffer.BlockCopy(buffer, 2, p.PaletteBuffer, 0, p.PaletteSize * 5); // save palette buffer in palette object al.Add(p); msg[0] = "ID: " + paletteId + ", update: " + paletteUpdate + ", " + p.PaletteSize + " entries"; return(p.PaletteSize); }
public PaletteInfo(PaletteInfo paletteInfo) { PaletteSize = paletteInfo.PaletteSize; PaletteBuffer = new byte[paletteInfo.PaletteBuffer.Length]; Buffer.BlockCopy(paletteInfo.PaletteBuffer, 0, PaletteBuffer, 0, PaletteBuffer.Length); }
/// <summary> /// decode palette from the input stream /// </summary> /// <param name="pic">SubPicture object containing info about the current caption</param> /// <returns>Palette object</returns> public BluRaySupPalette DecodePalette(BluRaySupPalette defaultPalette) { BluRaySupPicture pic = this; bool fadeOut = false; if (pic.Palettes.Count == 0 || pic.ObjectIdImage.PaletteId >= pic.Palettes.Count) { System.Diagnostics.Debug.Print("Palette not found in objectID=" + pic.ObjectId + " PaletteId=" + pic.ObjectIdImage.PaletteId + "!"); if (defaultPalette == null) { return(new BluRaySupPalette(256, Core.UsesBt601())); } else { return(new BluRaySupPalette(defaultPalette)); } } List <PaletteInfo> pl = pic.Palettes[pic.ObjectIdImage.PaletteId]; BluRaySupPalette palette = new BluRaySupPalette(256, Core.UsesBt601()); // by definition, index 0xff is always completely transparent // also all entries must be fully transparent after initialization for (int j = 0; j < pl.Count; j++) { PaletteInfo p = pl[j]; int index = 0; for (int i = 0; i < p.PaletteSize; i++) { // each palette entry consists of 5 bytes int palIndex = p.PaletteBuffer[index]; int y = p.PaletteBuffer[++index]; int cr, cb; if (Core.GetSwapCrCb()) { cb = p.PaletteBuffer[++index]; cr = p.PaletteBuffer[++index]; } else { cr = p.PaletteBuffer[++index]; cb = p.PaletteBuffer[++index]; } int alpha = p.PaletteBuffer[++index]; int alphaOld = palette.GetAlpha(palIndex); // avoid fading out if (alpha >= alphaOld || alpha == 0) { if (alpha < Core.GetAlphaCrop()) {// to not mess with scaling algorithms, make transparent color black y = 16; cr = 128; cb = 128; } palette.SetAlpha(palIndex, alpha); } else { fadeOut = true; } palette.SetYCbCr(palIndex, y, cb, cr); index++; } } if (fadeOut) { System.Diagnostics.Debug.Print("fade out detected -> patched palette\n"); } return(palette); }