⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavelet_form.pas

📁 jpeg and mpeg 编解码技术源代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
          GetMem(Cb, NWidth * NHeight * SizeOf(wv_pel));
          GetMem(Cr, NWidth * NHeight * SizeOf(wv_pel));
          wv_rgb_to_ycbcr(NWidth * NHeight, Channels[NumChannels].Data, Channels[NumChannels + 1].Data,
            Channels[NumChannels + 2].Data, Y, Cb, Cr);
          FreeMem(Channels[NumChannels].Data);
          Channels[NumChannels].Data := Y;
          FreeMem(Channels[NumChannels + 1].Data);
          Channels[NumChannels + 1].Data := Cb;
          FreeMem(Channels[NumChannels + 2].Data);
          Channels[NumChannels + 2].Data := Cr;
        end;
        Inc(NumChannels, 3);
      end;
      SourceImage.Free();
    end;
  end;

  if (node <> Nil) then
    TreeViewChannels.Selected := node; // and display

  TrackBarSizeBPPChange(TrackBarSizeBPP);
  ProgRec.Bar := ProgressBar1;
  ProgRec.MaxChannel := NumChannels - old_num_channels;
  if (PageControlSettings.ActivePage = TabSheetQuality) then
    max_bits := 0
  else
    max_bits := (Int64(NumChannels) * Int64(ImageWidth) * Int64(ImageHeight) * Int64(TrackBarSizeBPP.Position)) div Int64(1000);
  for i := old_num_channels to NumChannels - 1 do with Channels[i] do begin // initialise the new channels
    ProgRec.CurChannel := i - old_num_channels;
    Channel := wv_init_channel(ImageWidth, ImageHeight, Data, max_bits, 0, NumBlocks, ReorderTable, @wv_progress, @ProgRec);
    if (Channel = Nil) then
      break; // abort loop if we quit
  end;
  EnableUI();
end;

procedure TFormWavelet.CheckBoxGreyScaleClick(Sender: TObject);
begin
  CheckBoxYCbCr.Enabled := not CheckBoxGreyScale.Checked;
end;

procedure TFormWavelet.TreeViewChannelsChange(Sender: TObject; Node: TTreeNode);
var
  idx, subidx: Integer;
  row: PByteArray;
  x, y: Integer;
  r, g, b: pawv_pel;
  SourceImage: TBitmap;
  did_cstats: Boolean;
  mse: Single;
begin
  if (Node = Nil) then
    Exit;
  did_cstats := False;
  idx := Integer(Node.Data) shr 16;
  subidx := Integer(Node.Data) and $ffff;
  if (idx + subidx < NumChannels) then begin
    SourceImage := TBitmap.Create();
    SourceImage.PixelFormat := pf24bit;
    SourceImage.Width := ImageWidth;
    SourceImage.Height := ImageHeight;
    if ((Node.Parent = Nil) and not (Channels[idx].IsGreyScale)) then begin // got a group (rgb or yuv)
      if (Channels[idx].DidYCbCr) then begin
        GetMem(r, NWidth * NHeight * SizeOf(wv_pel));
        GetMem(g, NWidth * NHeight * SizeOf(wv_pel));
        GetMem(b, NWidth * NHeight * SizeOf(wv_pel));
        wv_ycbcr_to_rgb(NWidth * NHeight, Channels[idx].Data, Channels[idx + 1].Data,
          Channels[idx + 2].Data, r, g, b);
      end else begin
        r := Channels[idx + 0].Data;
        g := Channels[idx + 1].Data;
        b := Channels[idx + 2].Data;
      end;
    end else begin // grey
      if (Channels[idx + subidx].max_mse = 0.0) then
        TrackBarPSNR.Position := TrackBarPSNR.Min
      else
        TrackBarPSNR.Position := TrackBarPSNR.Max - Round(TrackBarPSNR.PageSize * mse_to_psnr(Channels[idx + subidx].max_mse));

      TrackBarDeltaMSE.Position := TrackBarDeltaMSE.Max div 2 + Round(Channels[idx + subidx].delta_mse * 1000.0);

      if (Channels[idx + subidx].CData <> Nil) then begin
        did_cstats := True;
        EditOutRMSE.Text := Format('%7.3f', [Sqrt(Channels[idx + subidx].out_mse)]);
        EditOutMSE.Text := Format('%7.3f', [Channels[idx + subidx].out_mse]);
        if (Channels[idx + subidx].out_mse = 0.0) then
          EditOutPSNR.Text := 'lossless'
        else
          EditOutPSNR.Text := Format('%7.3f', [mse_to_psnr(Channels[idx + subidx].out_mse)]);
      end;

      r := Channels[idx + subidx].Data;
      g := Channels[idx + subidx].Data;
      b := Channels[idx + subidx].Data;
    end;

    for y := 0 to ImageHeight - 1 do begin
      row := SourceImage.ScanLine[y];
      for x := 0 to ImageWidth - 1 do begin
        row[x * 3 + ofs_R] := Min(255, Max(0, r[y * NWidth + x]));
        row[x * 3 + ofs_G] := Min(255, Max(0, g[y * NWidth + x]));
        row[x * 3 + ofs_B] := Min(255, Max(0, b[y * NWidth + x]));
      end;
    end;

    if (not did_cstats) then begin
      mse := 0.0;
      x := 0;
      for y := 0 to NumChannels - 1 do if (Channels[y].CData <> Nil) then begin
        mse := mse + Channels[y].out_mse;
        Inc(x);
      end;
      if (x > 0) then begin
        mse := mse / x;
        EditOutRMSE.Text := Format('%7.3f', [Sqrt(mse)]);
        EditOutMSE.Text := Format('%7.3f', [mse]);
        if (mse = 0.0) then
          EditOutPSNR.Text := 'lossless'
        else
          EditOutPSNR.Text := Format('%7.3f', [mse_to_psnr(mse)]);
      end else begin
        EditOutRMSE.Text := '';
        EditOutMSE.Text := '';
        EditOutPSNR.Text := '';
      end;
    end;

    FormImage.Constraints.MaxWidth := ImageWidth + ScrollBarX;
    FormImage.Constraints.MaxHeight := ImageHeight + ScrollBarY;
    FormImage.Image.Width := ImageWidth;
    FormImage.Image.Height := ImageHeight;
    FormImage.Image.Picture.Bitmap := SourceImage;
    FormImage.Visible := True;

    if (Channels[idx].CData <> Nil) then begin // now for compressed image
      if ((Node.Parent = Nil) and not (Channels[idx].IsGreyScale)) then begin // got a group (rgb or yuv)
        if (Channels[idx].DidYCbCr) then begin
          wv_ycbcr_to_rgb(NWidth * NHeight, Channels[idx].CData, Channels[idx + 1].CData,
            Channels[idx + 2].CData, r, g, b);
        end else begin
          r := Channels[idx + 0].CData;
          g := Channels[idx + 1].CData;
          b := Channels[idx + 2].CData;
        end;
      end else begin
        r := Channels[idx + subidx].CData;
        g := Channels[idx + subidx].CData;
        b := Channels[idx + subidx].CData;
      end;

      for y := 0 to ImageHeight - 1 do begin
        row := SourceImage.ScanLine[y];
        for x := 0 to ImageWidth - 1 do begin
          row[x * 3 + ofs_R] := Min(255, Max(0, r[y * NWidth + x]));
          row[x * 3 + ofs_G] := Min(255, Max(0, g[y * NWidth + x]));
          row[x * 3 + ofs_B] := Min(255, Max(0, b[y * NWidth + x]));
        end;
      end;

      FormCImage.Constraints.MaxWidth := ImageWidth + ScrollBarX;
      FormCImage.Constraints.MaxHeight := ImageHeight + ScrollBarY;
      FormCImage.Image.Width := ImageWidth;
      FormCImage.Image.Height := ImageHeight;
      FormCImage.Image.Picture.Bitmap := SourceImage;
      FormCImage.Visible := True;
    end;

    if ((Node.Parent = Nil) and Channels[idx].DidYCbCr) then begin
      FreeMem(r);
      FreeMem(g);
      FreeMem(b);
    end;

    SourceImage.Free();
  end;
end;

procedure TFormWavelet.CheckBoxStayOnTopClick(Sender: TObject);
begin
  if (CheckBoxStayOnTop.Checked) then
    FormStyle := fsStayOnTop
  else
    FormStyle := fsNormal;
end;

procedure TFormWavelet.ButtonClearClick(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to NumChannels - 1 do with Channels[i] do begin
    if (Data <> Nil) then
      FreeMem(Data);
    if (CData <> Nil) then
      FreeMem(CData);
    wv_done_channel(Channel, Integer(i = 0));
    Data := Nil;
    CData := Nil;
    Channel := Nil;
  end;
  NumChannels := 0;
  NWidth := 0;
  NHeight := 0;
  ImageWidth := 0;
  ImageHeight := 0;
  ReorderTable := Nil;
  NumBlocks := 0;
  TrackBarSizeBPPChange(TrackBarSizeBPP);
  TreeViewChannels.Items.Clear();
  FormImage.Visible := False;
  FormImage.Image.Picture := Nil;
  FormCImage.Visible := False;
  FormCImage.Image.Picture := Nil;
  ButtonKompress.Enabled := False;
  GroupBoxChannels.Caption := 'Channels:';
  EditBits.Clear();
  EditKiloBytes.Clear();
  EditBPP.Clear();
  EditOutPSNR.Clear();
  EditOutMSE.Clear();
  EditOutRMSE.Clear();
end;

procedure TFormWavelet.TrackBarPSNRChange(Sender: TObject);
var
  idx, subidx: Integer;
begin
  if (Sender is TTrackBar) then begin
    if ((Sender as TTrackBar).Position = (Sender as TTrackBar).Min) then begin
      EditPSNR.Text := 'lossless';
      EditMSE.Text := Format('%7.3f', [0.0]);
    end else begin
      EditPSNR.Text := Format('%7.3f', [((Sender as TTrackBar).Max - (Sender as TTrackBar).Position) / (Sender as TTrackBar).PageSize]);
      EditMSE.Text := Format('%7.3f', [Sqrt(psnr_to_mse(((Sender as TTrackBar).Max - (Sender as TTrackBar).Position) / (Sender as TTrackBar).PageSize))]);
    end;
    if (TreeViewChannels.Selected <> Nil) then begin
      idx := Integer(TreeViewChannels.Selected.Data) shr 16;
      subidx := Integer(TreeViewChannels.Selected.Data) and $ffff;
      if ((TreeViewChannels.Selected.Parent = Nil) and not (Channels[idx].IsGreyScale)) then begin // got a group (rgb or yuv)
        ApplySettings([SMaxMSE], Channels[idx + 0]);
        ApplySettings([SMaxMSE], Channels[idx + 1]);
        ApplySettings([SMaxMSE], Channels[idx + 2]);
      end else begin
        ApplySettings([SMaxMSE], Channels[idx + subidx]);
      end;
    end;
  end;
end;

procedure TFormWavelet.ButtonKompressClick(Sender: TObject);
var
  ChPar: array[0..wv_MAX_CHANNELS - 1] of t_wv_mchannel_params;
  Sets: array[0..wv_MAX_CHANNELS - 1] of tp_wv_csettings;
  i, bits: Integer;
  bf: tp_bit_file;
  mem: PByteArray;
  dc: tp_wv_dchannels;
  MaxBits: Integer;
  fname: String;
  save_as_bmp: Boolean;
begin
     for i := 0 to wv_MAX_CHANNELS - 1 do
    Sets[i] := Nil;
  EditBits.Text := '';
  EditKiloBytes.Text := '';
  EditBPP.Text := '';
  EditOutPSNR.Text := '';
  EditOutMSE.Text := '';
  EditOutRMSE.Text := '';
  if (NumChannels > 0) then begin
    if (PageControlSettings.ActivePage = TabSheetQuality) then begin
      for i := 0 to NumChannels - 1 do begin
        ChPar[i].cc := Channels[i].Channel;
        ChPar[i].max_mse := Channels[i].max_mse;
      end;
      bits := wv_init_multi_channels(0, 1.0, NumChannels, @ChPar, @Sets);
    end else begin
      for i := 0 to NumChannels - 1 do begin
        ChPar[i].cc := Channels[i].Channel;
        ChPar[i].max_mse := Sqr(Sqr(Channels[i].delta_mse));
        if (Channels[i].delta_mse > 0.0) then
          ChPar[i].max_mse := -ChPar[i].max_mse; // reverse sign
      end;
      MaxBits := (Int64(NumChannels) * Int64(ImageWidth) * Int64(ImageHeight) * Int64(TrackBarSizeBPP.Position)) div Int64(1000);
      bits := wv_init_multi_channels(MaxBits, 0.0, NumChannels, @ChPar, @Sets);
    end;
    if (bits > 0) then begin
      bf := Nil;
      fname := '';
      save_as_bmp := False;
      if (CheckBoxSave.Checked and SaveDialog1.Execute()) then begin
        fname := SaveDialog1.FileName;
        save_as_bmp := AnsiCompareFileName(ExtractFileExt(fname), '.BMP') = 0;
      end;
      if ((fname <> '') and (not save_as_bmp)) then begin
        bf := bit_open(PChar(fname), 'wb', 0);
        if (bf = Nil) then
          fname := '';
      end;
      if (bf = Nil) then
        bf := bit_open(Nil, 'wm', wv_MAX_HEADER_SIZE + bits);
      if (bf <> Nil) then begin
        bit_write(Integer(Channels[0].DidYCbCr), 1, bf);
        wv_encode_channels(NumChannels, @Sets, bf);
        mem := Nil;
        bits := bit_close(bf, @mem);

        if (mem <> Nil) then
          bf := bit_open(Pointer(mem), 'rm', bits) // open from mem
        else
          bf := bit_open(PChar(fname), 'rb', bits);
        bit_read(1, bf); // skip YCbCr flag
        dc := wv_init_decode_channels(bf);
        if (dc <> Nil) then begin
          for i := 0 to NumChannels - 1 do with Channels[i] do begin
            if (CData <> Nil) then
              FreeMem(CData);
            GetMem(CData, dc^.width * dc^.height * SizeOf(wv_pel));
            Move(dc^.channels^[i]^, CData^, dc^.width * dc^.height * SizeOf(wv_pel));
            wv_calc_psnr(Data, CData, ImageWidth, ImageHeight, NWidth, out_mse);
          end;
          wv_done_decode_channels(dc);
          EditBits.Text := IntToStr(bits);
          EditKiloBytes.Text := Format('%7.3f', [bits / 8192.0]);
          EditBPP.Text := Format('%7.3f', [bits / (NumChannels * ImageWidth * ImageHeight)]);
          TreeViewChannelsChange(Self, TreeViewChannels.Selected);
          if ((fname <> '') and save_as_bmp) then
            FormCImage.Image.Picture.SaveToFile(fname);
        end;
        bit_close(bf, Pointer(mem)); // frees the pointer
      end;
    end;
    for i := 0 to NumChannels - 1 do
      if (Sets[i] <> Nil) then
        wv_done_channel_settings(Sets[i]);
  end;
end;

procedure TFormWavelet.TrackBarSizeBPPChange(Sender: TObject);
begin
  if (Sender is TTrackBar) then begin
    EditSizeBPP.Text := Format('%.3f', [(Sender as TTrackBar).Position / 1000.0]);
    EditSizeSize.Text := Format('%.3f', [(Int64(NumChannels) * Int64(ImageWidth) * Int64(ImageHeight) * Int64((Sender as TTrackBar).Position)) / (1024.0 * 1000.0 * 8.0)]);
  end;
end;

procedure TFormWavelet.UpDownSizeChangingEx(Sender: TObject;
  var AllowChange: Boolean; NewValue: Smallint;
  Direction: TUpDownDirection);
begin
  if ((NewValue < TrackBarSizeBPP.Min) or (NewValue > TrackBarSizeBPP.Max)) then
    AllowChange := False
  else
    TrackBarSizeBPP.Max := MaxSizeTrack shr NewValue;
end;

procedure TFormWavelet.TrackBarDeltaMSEChange(Sender: TObject);
var
  idx, subidx: Integer;
  d: Single;
begin
  if (Sender is TTrackBar) then begin
    d := ((Sender as TTrackBar).Position - (Sender as TTrackBar).Max div 2) / 1000.0;
    if (d < 0) then
      d := -Sqr(d)
    else
      d := Sqr(d);
    EditDeltaMSE.Text := Format('%6.3f', [d]);
    if (TreeViewChannels.Selected <> Nil) then begin
      idx := Integer(TreeViewChannels.Selected.Data) shr 16;
      subidx := Integer(TreeViewChannels.Selected.Data) and $ffff;
      if ((TreeViewChannels.Selected.Parent = Nil) and not (Channels[idx].IsGreyScale)) then begin // got a group (rgb or yuv)
        ApplySettings([SDeltaMSE], Channels[idx + 0]);
        ApplySettings([SDeltaMSE], Channels[idx + 1]);
        ApplySettings([SDeltaMSE], Channels[idx + 2]);
      end else begin
        ApplySettings([SDeltaMSE], Channels[idx + subidx]);
      end;
    end;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -