fix(totp): scan QR ecran - indices Byte dans ZXing (boucle infinie a 100 % CPU)
ZXing.Delphi declarait rgbIndex/luminanceIndex en Byte dans les conversions octets bruts -> luminance : au-dela de 255 ils repassaient a 0, la boucle ne finissait jamais. L'APK n'y passait pas (CreateFromBitmap). Mesure apres correctif : 60 ms sur un ecran 1920x1080 avec TRY_HARDER, 86 ms sans QR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -364,7 +364,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceRGB24(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
r, g, b : Integer;
|
r, g, b : Integer;
|
||||||
begin
|
begin
|
||||||
rgbIndex := 0;
|
rgbIndex := 0;
|
||||||
@@ -389,7 +389,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceBGR24(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
b, g, r : Byte;
|
b, g, r : Byte;
|
||||||
begin
|
begin
|
||||||
rgbIndex := 0;
|
rgbIndex := 0;
|
||||||
@@ -414,7 +414,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceRGB32(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
r, g, b : Byte;
|
r, g, b : Byte;
|
||||||
begin
|
begin
|
||||||
rgbIndex := 0;
|
rgbIndex := 0;
|
||||||
@@ -439,7 +439,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceBGR32(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
b, g, r : Byte;
|
b, g, r : Byte;
|
||||||
begin
|
begin
|
||||||
rgbIndex := 0;
|
rgbIndex := 0;
|
||||||
@@ -464,7 +464,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceBGRA32(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
b, g, r,
|
b, g, r,
|
||||||
alpha : Byte;
|
alpha : Byte;
|
||||||
luminance : Byte;
|
luminance : Byte;
|
||||||
@@ -495,7 +495,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceRGBA32(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
r, g, b,
|
r, g, b,
|
||||||
alpha : Byte;
|
alpha : Byte;
|
||||||
luminance : Byte;
|
luminance : Byte;
|
||||||
@@ -526,7 +526,7 @@ procedure TRGBLuminanceSource.CalculateLuminanceARGB32(
|
|||||||
const rgbRawBytes: TArray<Byte>);
|
const rgbRawBytes: TArray<Byte>);
|
||||||
var
|
var
|
||||||
rgbIndex,
|
rgbIndex,
|
||||||
luminanceIndex,
|
luminanceIndex : Integer; // pmserver: etaient Byte -> boucle infinie au-dela de 255 octets
|
||||||
r, g, b,
|
r, g, b,
|
||||||
alpha : Byte;
|
alpha : Byte;
|
||||||
luminance : Byte;
|
luminance : Byte;
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ interface
|
|||||||
|
|
||||||
/// Texte du premier QR trouve a l'ecran, '' si aucun.
|
/// Texte du premier QR trouve a l'ecran, '' si aucun.
|
||||||
function ScanScreenForQr: string;
|
function ScanScreenForQr: string;
|
||||||
|
// Exposees pour le banc d'essai (mesure du temps de decodage).
|
||||||
|
function CaptureVirtualScreen(out AWidth, AHeight: Integer): TArray<Byte>;
|
||||||
|
function DecodeQrPixels(const APixels: TArray<Byte>; AW, AH: Integer;
|
||||||
|
ATryHarder: Boolean): string;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@@ -65,10 +69,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ScanScreenForQr: string;
|
function DecodeQrPixels(const APixels: TArray<Byte>; AW, AH: Integer;
|
||||||
|
ATryHarder: Boolean): string;
|
||||||
var
|
var
|
||||||
LPixels: TArray<Byte>;
|
|
||||||
LW, LH: Integer;
|
|
||||||
LSource: TLuminanceSource;
|
LSource: TLuminanceSource;
|
||||||
LBinarizer: THybridBinarizer;
|
LBinarizer: THybridBinarizer;
|
||||||
LImage: TBinaryBitmap;
|
LImage: TBinaryBitmap;
|
||||||
@@ -78,19 +81,16 @@ var
|
|||||||
LRes: TReadResult;
|
LRes: TReadResult;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
LPixels := CaptureVirtualScreen(LW, LH);
|
|
||||||
if LPixels = nil then Exit;
|
|
||||||
|
|
||||||
LFormats := TList<TBarcodeFormat>.Create;
|
LFormats := TList<TBarcodeFormat>.Create;
|
||||||
LFormats.Add(TBarcodeFormat.QR_CODE);
|
LFormats.Add(TBarcodeFormat.QR_CODE);
|
||||||
LHints := TDictionary<TDecodeHintType, TObject>.Create;
|
LHints := TDictionary<TDecodeHintType, TObject>.Create;
|
||||||
LHints.Add(TDecodeHintType.POSSIBLE_FORMATS, LFormats);
|
LHints.Add(TDecodeHintType.POSSIBLE_FORMATS, LFormats);
|
||||||
LHints.Add(TDecodeHintType.TRY_HARDER, nil);
|
if ATryHarder then LHints.Add(TDecodeHintType.TRY_HARDER, nil);
|
||||||
LReader := TMultiFormatReader.Create;
|
LReader := TMultiFormatReader.Create;
|
||||||
LReader.Hints := LHints;
|
LReader.Hints := LHints;
|
||||||
// BGR32 et non BGRA32 : le 4e octet d'une capture GDI vaut 0, et la
|
// BGR32 et non BGRA32 : le 4e octet d'une capture GDI vaut 0, et la
|
||||||
// conversion BGRA le lirait comme une transparence totale - image blanche.
|
// conversion BGRA le lirait comme une transparence totale - image blanche.
|
||||||
LSource := TRGBLuminanceSource.Create(LPixels, LW, LH, TBitmapFormat.BGR32);
|
LSource := TRGBLuminanceSource.Create(APixels, AW, AH, TBitmapFormat.BGR32);
|
||||||
LBinarizer := THybridBinarizer.Create(LSource);
|
LBinarizer := THybridBinarizer.Create(LSource);
|
||||||
LImage := TBinaryBitmap.Create(LBinarizer);
|
LImage := TBinaryBitmap.Create(LBinarizer);
|
||||||
LRes := nil;
|
LRes := nil;
|
||||||
@@ -112,4 +112,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ScanScreenForQr: string;
|
||||||
|
var
|
||||||
|
LPixels: TArray<Byte>;
|
||||||
|
LW, LH: Integer;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
LPixels := CaptureVirtualScreen(LW, LH);
|
||||||
|
if LPixels <> nil then Result := DecodeQrPixels(LPixels, LW, LH, True);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user