NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: problematika encodingu u celočíselných hodnot při čtení dat z jiných zdrojů.

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Petr Vocel
Tvůrce
Avatar
Petr Vocel:9.2.2017 15:01

narazil jsem při binárním čtení obrázku (PNG) na problém encodingu celočíselných konstant. Pátral jsem na intenetu a všechna řešení mi připadala jak škrábání se hráběmi. Nechtělo se mi věřit, že by to v C# nešlo alespoň trovhu inteligentně. Nakonec se mi v dokumentaci podařilo nalézt nastavení u bin. writeru resp readeru. Problém je, že mi to podle popisu nefunguje ani omylem. Stále se to chová úplně stejně. Jak s parametrem, tak bez něj. Přikládám testovací program.
Nemáte někdo s tím nějaké větší zkušenosti ? Díky
Petr
using System;
using System.Collec­tions.Generic;
using System.Linq;
using System.Text;
using System.Threadin­g.Tasks;
using System.IO;

namespace ConsoleApplication2
{
class Program
{
const string fileName = "AppSettingsX.dat";

static void Main()
{
WriteDefaultVa­lues();
DisplayValues();
Console.ReadKey();
}
public static void WriteDefaultVa­lues()
{
using (BinaryWriter writer = new BinaryWriter(Fi­le.Open(fileNa­me, FileMode.Create)))
{
writer.Write(1­.250F);
writer.Write(@"c:\Tem­p");
writer.Write(10);
writer.Write((u­long) 0x1234);
writer.Write(true);
}
}

public static void DisplayValues()
{
float aspectRatio;
string tempDirectory;
int autoSaveTime;
ulong moje;
bool showStatusBar;

if (File.Exists(fi­leName))
{
UTF32Encoding mujEnkoding = new UTF32Encoding(true, true);

using (BinaryReader reader = new BinaryReader(Fi­le.Open(fileNa­me, FileMode.Open),mu­jEnkoding ))
{
aspectRatio = reader.ReadSin­gle();
tempDirectory = reader.ReadStrin­g();
autoSaveTime = reader.ReadInt32();
moje = reader.ReadUIn­t32();
showStatusBar = reader.ReadBo­olean();

}

Console.Write­Line("Aspect ratio set to: " + aspectRatio);
Console.Write­Line("Temp directory is: " + tempDirectory);
Console.Write­Line("Auto save time set to: " + autoSaveTime);
Console.Write­Line("Show status bar: " + showStatusBar);
Console.Write­Line("Moje uint: " + moje.ToString("X8"));
}
}
}
}

 
Odpovědět
9.2.2017 15:01
Avatar
HONZ4
Člen
Avatar
Odpovídá na Petr Vocel
HONZ4:9.2.2017 18:16

Nikdy jsem sice specifikaci PNG nestudoval, a navíc jsi ani přesně nepopsal problém. Ale protože nevidím, že by si v kódu někde přehazoval endianitu. Tipoval bych, že problém bude tam. A taky PNG je docela starý formát, tak bych očekával spíše kódování ASCII.

using (BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open), Encoding.ASCII))

(pro vkládání kódu slouží tlačítko </>)

 
Nahoru Odpovědět
9.2.2017 18:16
Avatar
Odpovídá na Petr Vocel
Neaktivní uživatel:9.2.2017 19:04

Já měl zato, že Encoding nemá nikdy vliv na kódování celočíeelných konstant, jenom Endianita. A ta by měla být na dnešních x86-64 CPU vždy little-endian. A ty specifikuješ u

UTF32Encoding mujEnkoding = new UTF32Encoding(true, true);

BigEndian. Zkus ten první parametr změnit na false. A vidím, že GetPreamble() taky nevoláš (a ani ji nečekám u binárního souboru, maximálně u txt), takže ten druhý bys mohl dát taky false. Pozkoušej - vše beru odsud: https://msdn.microsoft.com/…vs.110).aspx

Editováno 9.2.2017 19:05
Nahoru Odpovědět
9.2.2017 19:04
Neaktivní uživatelský účet
Avatar
Petr Vocel
Tvůrce
Avatar
Odpovídá na Neaktivní uživatel
Petr Vocel:9.2.2017 19:32

samozřejmě, že se jedná o endianitu, to byl můj překlep lépe řečeno renonc. Informace jsem čerpal ze stejného zdroje a zkoušel jsem obojí jak false tak true. Podle uvedeného zdroje je false předdefinováno. viz example.
Jinak soubor si bohužel nenavrhuji. Jedná se o přípravu na vyhodnocování obrazu a hledání objektů na obrazech. A obrázek byl dodán v tomto formátu, který je pro danou záležitost celkem vhodný. Ve vnitřní struktuře jsou potom 4 bytové čítače délek jednotlivých oblastí atd. samozřejmě, že v nelhorším to přečtu po bytech a složím si to, ale to jsou ty hrábě které jsem dělal před 40 lety v assembleru a teď jsem doufal, že to v C# bude dál. Protože jinak po načtení mám byty přeházené a nemohu to jako čítač bez úprav použít. Co jsem se ale díval na internetu, tak to spíš ke skrytým hrábím směřuje přes načtení jinam a konvezi do proměnné. Nevím proč se prosadila edianita small ale high byla z dob, kdy nejmenší adresovatelnou jednotkou bylo slovo, vetšinou 32 bitové, a tam byla při malé endianitě bitů v registrech přirozeným výsledkem, při binárním zápisu větší části paměti. To by u bytových adress nemělo rychlost výpočtu prakticky ovlivňovat. Jinak díky.

 
Nahoru Odpovědět
9.2.2017 19:32
Avatar
HONZ4
Člen
Avatar
Odpovídá na Petr Vocel
HONZ4:9.2.2017 19:59

Ať to uděláš tak nebo tak, (jak i píše Lukas) nastavení Encoding má pouze vliv na čtení textu, ne hodnot. Takže pokud (jak si myslím, protože vznikl někdy v 90's) jsou v png čísla uloženy jako big-endian, tak je musíš swapnout po načtení.

Editováno 9.2.2017 20:02
 
Nahoru Odpovědět
9.2.2017 19:59
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.