একটি জিআইএফ এনকোডার লিখুন


9

হ্যাঁ, ভাল পুরানো জিআইএফ বহুমুখীতার জন্য পছন্দ, তার পেটেন্টদের জন্য ঘৃণা এবং এর সীমাবদ্ধতার কারণে (এবং পেটেন্টগুলি) আংশিকভাবে অপ্রচলিত, জিআইএফ মূলত একটি রঙ প্যালেট এবং এলজেডব্লিউ অ্যালগরিদম ব্যবহার করে সংকুচিত একটি প্যালেট-সূচিযুক্ত চিত্র ধারণ করে।

আপনার কাজটি এমন একটি প্রোগ্রাম লিখুন যা স্ট্যান্ডার্ড ইনপুট থেকে ASCII পিপিএম ফর্ম্যাটে ("P3" ম্যাজিক নম্বর) একটি চিত্র পড়ে এবং স্ট্যান্ডার্ড আউটপুটে একই চিত্র (অভিন্ন পিক্সেল-বাই-পিক্সেল) জিআইএফ ফর্ম্যাটে লেখেন। আউটপুট হয় বাইনারি আকারে, বা ASCII পাঠ্য প্রতিটি বাইট সহ 0 এবং 255 (অন্তর্ভুক্ত) এর মধ্যে একটি সংখ্যা দ্বারা উপস্থাপিত হয়, যা সাদা স্থান দ্বারা পৃথক করা হয়।

ইনপুট চিত্রটিতে 256 টিরও বেশি রঙ না থাকার গ্যারান্টিযুক্ত।

স্কোরিং:

আপনার প্রোগ্রামটি 3 টি নমুনা চিত্রের উপর পরীক্ষা করা হবে এবং আপনার স্কোর হিসাবে গণনা করা হবে:
প্রোগ্রামের আকার + সমষ্টি (প্রতিটি নমুনা চিত্রের জন্য আউটপুট আকার - রেফারেন্স আকার)
সর্বনিম্ন স্কোর জয়।

প্রয়োজনীয়তা:

  • আপনার প্রোগ্রামটি অবশ্যই বিভিন্ন আকারের যেকোন ধরণের চিত্রের সাথে কাজ করবে এবং নমুনা চিত্রগুলিতে সীমাবদ্ধ থাকবে না। উদাহরণস্বরূপ, আপনি মাত্রাগুলি 2 টির গুণিতকগুলিতে সীমাবদ্ধ করতে পারেন বা ধরে নিতে পারেন পিপিএম সর্বাধিক রঙ 255, তবে এটি এখনও বিভিন্ন ধরণের ইনপুট চিত্রের সাথে কাজ করা উচিত।
  • আউটপুটটি অবশ্যই একটি বৈধ জিআইএফ ফাইল হতে হবে যা কোনও আনুগত্যমূলক প্রোগ্রামের সাথে লোড হতে পারে (ASCII আউটপুট বিকল্পটি ব্যবহার করে বাইনারিতে ফিরে রূপান্তর করার পরে)।
  • আপনি কোনও ইমেজ প্রসেসিং ফাংশন (অন্তর্নির্মিত বা তৃতীয় পক্ষ) ব্যবহার করতে পারবেন না, আপনার প্রোগ্রামে অবশ্যই সমস্ত প্রাসঙ্গিক কোড থাকতে হবে।
  • আপনার প্রোগ্রামটি লিনাক্সে অবাধে উপলভ্য সফ্টওয়্যার ব্যবহার করে চলতে হবে।
  • উত্স কোডটিতে কেবলমাত্র ASCII অক্ষর ব্যবহার করা উচিত।

নমুনা চিত্র:

এখানে 3 টি নমুনা চিত্র যা স্কোর করার জন্য ব্যবহৃত হবে। আপনি পিপিএম ফাইলগুলির সাথে একটি জিপ সংরক্ষণাগার ডাউনলোড করতে পারেন (সেই পৃষ্ঠার শীর্ষে ডাউনলোড বোতামটি ব্যবহার করুন)। অথবা আপনি নীচের কমান্ডের সাথে চিত্রম্যাগিক ব্যবহার করে নীচের পিএনজি চিত্রগুলি থেকে তাদের রূপান্তর করতে পারেন:

convert file.png -compress none file.ppm

আমি নিশ্চিতকরণের জন্য পিপিএম ফাইলগুলির MD5 চেকসামও সরবরাহ করছি।

1. অ্যাম্বার

amber.png

রেফারেন্সের আকার:
পিপিএমের 38055 এমডি 5 চেকসাম: d1ad863cb556869332074717eb278080

2. নীল চোখ

blueeyes.png

রেফারেন্সের আকার:
পিপিএমের 28638 এমডি 5 চেকসাম: e9ad410057a5f6c25a22a534259dcf3a

3. মরিচ

peppers.png

রেফারেন্সের আকার:
পিপিএমের 53586 এমডি 5 চেকসাম: 74112dbdbb8b7de5216f9e24c2e1a627


1
মডারেটর দ্রষ্টব্য: অফ-টপিক / অপ্রচলিত মন্তব্য সরানো হয়েছে। এই প্রশ্নের নমুনা চিত্রগুলি নিয়ে আলোচনার জন্য দয়া করে মেটা দেখুন
ডুরকনব

দেখে মনে হচ্ছে দ্বিতীয় চিত্রটির সাথে এরকম কিছু ব্যবহার করা হয়েছিল: Websiteoptimization.com / Speed/ tweak / lossy যা আরও ভাল সংকোচনের অনুপাত এবং এলজেডব্লু এনকোডার টুইটের সংবেদনশীলতা ব্যাখ্যা করবে।
নটকি

1
"উত্স কোডটিতে কেবলমাত্র ASCII অক্ষর ব্যবহার করা উচিত” "- সুতরাং, অন্য কথায়, আমাদের এপিএলে এই চ্যালেঞ্জটি করার অনুমতি দেওয়া হচ্ছে না?
FUZxxl

@FUZxxl সত্য, তবে আপনি জে ব্যবহার করতে পারেন আপনাকে অহুই ব্যবহার করতে বা গল্ফস্ক্রিপ্ট / সিজেমে বেস রূপান্তর কৌশলগুলিও অনুমোদিত নয় not
অ্যাডিটসু ছেড়ে গেছে কারণ এসই 20:59

উত্তর:


4

পার্ল, 515 + -2922 + 0 + -2571 = -4978

অন্য পদ্ধতির। এবার আমি ছবিটি 64xH সাইজের টাইলসে সংরক্ষণ করার চেষ্টা করছি। চশমা অনুসারে এটি ঠিক আছে তবে কিছু সফ্টওয়্যার কেবল প্রথম টাইল বা একটি অ্যানিমেশন প্রদর্শন করতে পারে। টাইলগুলি আরও ভাল সংকীর্ণতার কারণে সংকুচিত হয়। আমি এখনও দ্বিতীয় চিত্রের পাশাপাশি সাধারণ সংকোচনের কাজ করি এবং যা সংক্ষিপ্ত আসে তা চয়ন করি। যেহেতু এটি চিত্রটিকে দু'বার সংকুচিত করে, এটি আমার আগের সমাধানের তুলনায় দ্বিগুণ ধীর।

#!perl -n0
sub r{$r.=1&"@_">>$_ for 0..log(@d|256)/log 2}
@k=/(\d+) (\d+)/;
@l=map{$$_||=(push(@t,split$"),++$i)}/\d+ \d+ \d+/g;
print+GIF89a,pack(vvCxxC768,@k,~8,@t);
sub v{($w,$h)=@_;for$k(0.."@k"/$w-1){
$k*=$w;$r='';@d=();@p=grep+($z++-$k)%"@k"<$w,@l;
$"=' ';$_="@p ";$"='|';while(/./){
r 256;%d=map{($_,$_-1)}@d=1..256;
$d{$&}=@d+2,r$d{$1},unshift@d,$&while@d<4095&&s/^(@d) (\d*)/$2/}
r 257;$_=pack"b*",$r;
$h.=pack"Cv4n(C/a)*",44,$k,0,$w,$k[1],8,/.{0,255}/gs
}$b=$h if!$b||length$b>length$h}
"@k"%64||v 64;v"@k";print"$b;"

পার্ল, 354 + 12 + 0 + -1 = 365 418 9521 51168 56639

হয় আমার কোডে কিছু ত্রুটি রয়েছে বা দ্বিতীয় চিত্রটি নির্দিষ্ট এনকোডারটির জন্য অনুকূলিত হয়েছে কারণ আপাতদৃষ্টিতে তুচ্ছ পরিবর্তন হ'ল আকারটিকে হুবহু হ্রাস করেছে। প্রতি চিত্র প্রায় 30s-60s লাগে।

গল্ফ সংস্করণ।

#!perl -n0
sub r{$r.=1&"@_">>$_ for 0..log(@d|256)/log 2}
@k=/(\d+) (\d+)/;
@p=map{$$_||=(push(@t,split$"),++$i)}/\d+ \d+ \d+/g;
$_="@p ";$"='|';while(/./){
r 256;%d=map{($_,$_-1)}@d=1..256;
$d{$&}=@d+2,r$d{$1},unshift@d,$&while@d<4095&&s/^(@d) (\d*)/$2/}
r 257;$_=pack"b*",$r;
print+GIF89a,pack(vvCxxC768,@k,~8,@t),
pack("Cx4vvn(C/a)*",44,@k,8,/.{0,255}/gs),';'

কোনও জিআইএফ সংকোচকারী একমাত্র সিদ্ধান্ত নিতে পারে যখন এলজেডাব্লু অভিধানটি রিসেট করা যায়। সাধারণভাবে এই কাজের জন্য চিত্রগুলি কীভাবে সেরা মুহুর্তটি বেছে নেওয়া হয়েছিল তা হ'ল প্রতিটি 4096 কোড যা অভিধানটি উপচে পড়ার মুহুর্তেই। এই সীমাবদ্ধতার সাথে অভিধানটি কখনই উপচে পড়ে না যা বাস্তবায়নে কয়েকটা বাইট সংরক্ষণ করে। এটি বিস্তারিতভাবে কাজ করে:

#!perl -n0
# function to add one codeword to the output stream @r.
# the current codeword length is based on the dictionary size/
sub r{push@r,map"@_">>$_,0..log(@d|256)/log 2}
# get the dimensions into @k
@k=/(\d+) (\d+)/;
# get pixel indexes to @p and palette to @t
@p=map{$$_||=(push(@t,split$"),++$i)}/\d+ \d+ \d+/g;
# convert index table into space separated string 
$_="@p ";$"='|';
# LZW encoder; while something to encode
while(/\S/){
# output reset code
r 256;
# reset code dictionary $d is the last code number,
# %d is the map of codes and @d list of codes
$d=257;%d=map{($_,$_-1)}@d=1..256;
# find codes using regexp, stop at dictionary overflow
while($d<4096&&s/^(@d) (\d*)/$2/){
unshift@d,$&;$d{$&}=++$d;r$d{$1}}}
# end LZW encoder; output end code
r 257;
# convert bit string @r to bytes $f
vec($f,$j++,1)=$_ for@r;
# output header up to the color table
print+GIF89a,pack(vvCvC768,@k,~8,0,@t),
# output rest of the header
pack(Cv4CC,44,0,0,@k,0,8),
# output the LZW compressed data $f slicing into sub-blocks
$f=~s/.{0,255}/chr(length$&).$&/egsr,';'

পার্ল, 394 + -8 + 0 + -12 = 374

রিসেট পয়েন্টটি অনুমান করার জন্য একটি হিউরিস্টিক যুক্ত করা কমপ্রেসকে কিছুটা উন্নত করে তবে অতিরিক্ত কোডটি ন্যায়সঙ্গত করার পক্ষে যথেষ্ট নয়:

#!perl -n0
sub r{$r.=1&"@_">>$_ for 0..log(@d|256)/log 2}
@k=/(\d+) (\d+)/;
@p=map{$$_||=(push(@t,split$"),++$i)}/\d+ \d+ \d+/g;
$_="@p ";$"='|';while(/./){
r 256;%d=map{($_,$_-1)}@d=1..256;
$d{$&}=@d+2,r$d{$1},unshift@d,$&while
(@d<4001||(/((@d) ){11}/,$&=~y/ //>12))&@d<4095&&s/^(@d) (\d*)/$2/}
r 257;$_=pack"b*",$r;
print+GIF89a,pack(vvCxxC768,@k,~8,@t),
pack("Cx4vvn(C/a)*",44,@k,8,/.{0,255}/gs),';'

খুব সুন্দর! যদিও এটি প্রতি ছবিতে 30 এর বেশি সময় নেয়। আমি পূর্ববর্তী সংস্করণ থেকে -30 দিয়ে বেশ প্রভাবিত হয়েছি, আমি অবাক হয়েছি আপনি যদি পদ্ধতিগুলি একত্রিত করতে পারেন এবং একটি কম স্কোর পেতে পারেন। এছাড়াও, আপনি প্রোগ্রামটি কি সম্পর্কে কিছুটা লিখতে পারেন?
অডিটসু ছাড়ুন কারণ এসই 15-10

প্রস্থটি
64৪ এর

@ অ্যাডিটসু, এটির প্রয়োজন নেই, প্রস্থটি যদি 64 এর একাধিক না হয় তবে টাইলিংয়ের পদ্ধতিটি চেষ্টা করা হয় না এবং নিয়মিত সংকোচনের ব্যবহার করা হয়। অবশ্যই আরও একটি 100 ডলার অক্ষর ব্যয় আমি শেষ টাইল পরিবর্তনশীল আকার করতে পারে।
নটকি

খুব ধীর এবং টাইলযুক্ত চিত্রগুলি অ্যানিমেশন হিসাবে দেখায়, তবে .. খুব ভাল হয়েছে, আপনি এগুলিকে আরও ছোট করে তুলতে পারেন তা দেখে এটি বেশ চিত্তাকর্ষক।
অ্যাডিটসু ছেড়ে গেছে কারণ এসই ইভিল

2

সিজেম, স্কোর 155 + 35306 + 44723 + 21518 = 101702

কেবল একটি বোবা রেফারেন্স বাস্তবায়ন। এটি ধীর, কোনও প্রকৃত সংকোচন করে না এবং এটি গল্ফ হয় না।

"GIF89a":iS*SqN/S*S%1>:i3/:M0=2<256f{md\}S*:ZS247S0S0SM1>_|:PL*_,768\m0a*+S*S44S0S0S0S0SZS0S8SM1>Pf{\a#}254/256a*{512+2b1>W%}%:+8/{W%2b}%255/{_,S@S*S}/0S59
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.