Wiki - BASIC

Simple Basic for Windows R3 - sourceforge

Simple Basic for Windows R3 - windows live

Reference from Jpeg (.jpg) Image Source Decoder by bkenwright@xbdev.net

and Jpeg Decoder Open Soruce Code,Copyright (C) 1995-1997, Thomas G. Lane.

Basic Version (c)copyright by 盧哲正 , all rights reserved.

jpeg-and-huffman-code

 

Decode .JPG files with Huffman Code

 

filename$="test.jpg"

input "Input filename",a$

if len(a$)>0 then filename$=a$

if instr(filename$,".")=0 then filename$=filename$+".jpg"

open filename$ for input as #1

small_mode=0

screen

seg_start=0

seg_type=0

jpeg_restart_flag=0

file_index=0

fetch_finish_flag=0

start_of_scan_count=0

break_flag=0

while break_flag=0 and eof(1)=0

  if fetch_finish_flag=0

  then

    a=asc(input$(1,#1))

    file_index=file_index+1

  else

    a=0xff

  endif

  if a=0xff and (file_index=seg_start+1 or fetch_finish_flag=1 or fetch_code_keep=0xff) then gosub 1000

  fetch_finish_flag=0

  fetch_finish_type=0

  if seg_type=0xC4 then gosub 2000

  if seg_type=0xDB then gosub 6000

  if seg_type=0xC0 or seg_type=0xC2 then gosub 7000

  if seg_type=0xDA then gosub 9000

wend

close #1

end

 

1000 rem get segment length

rem if seg_type=0xDA then seg_start=file_index-1

if fetch_finish_flag=0

then

  seg_type=asc(input$(1,#1))

  file_index=file_index+1

else

  seg_type=fetch_finish_type

  seg_start=seg_start-3

endif

seg_length_high=0

if fetch_finish_flag=0 and (seg_type<0xd0 or seg_type>0xd8)

then

  seg_length_high=asc(input$(1,#1))

  file_index=file_index+1

endif

seg_length=0

if seg_type<0xd0 or seg_type>0xd8

then

  seg_length=seg_length_high*256+asc(input$(1,#1))

  file_index=file_index+1

endif

if (seg_type<0xd0 or seg_type>0xd8) and seg_length=0 and fetch_finish_type<>0

then

  seg_length=seg_length_high*256+asc(input$(1,#1))

  seg_start=seg_start+1

  file_index=file_index+1

endif

 

if seg_type=0xDD

then

  jpeg_restart_interval=asc(input$(1,#1))*256+asc(input$(1,#1))

  file_index=file_index+2

  jpeg_restart_flag=1

endif

 

if seg_type=0xC0 then seg_info$="SOF0"

if seg_type=0xC1 then seg_info$="SOF1"

if seg_type=0xC2 then seg_info$="SOF2"

if seg_type=0xC4 then seg_info$="DHT"

if seg_type=0xC8 then seg_info$="JPG"

if seg_type=0xCC then seg_info$="DAC"

if (seg_type and 0xf0)=0xD0 then seg_info$="RST"

if seg_type=0xD8 then seg_info$="SOI"

if seg_type=0xD9 then seg_info$="EOI"

if seg_type=0xDA then seg_info$="SOS"

if seg_type=0xDB then seg_info$="DQT"

if seg_type=0xDC then seg_info$="DNL"

if seg_type=0xDD then seg_info$="DRI"

if seg_type=0xDE then seg_info$="DHP"

if seg_type=0xDF then seg_info$="EXP"

if (seg_type and 0xf0)=0xE0 then seg_info$="APP"+str$(seg_type and 0xf)

if seg_type=0xE1 then seg_info$="APP1"

if seg_type=0xEF then seg_info$="APP15"

if seg_type=0xF0 then seg_info$="JPG0"

if seg_type=0xFD then seg_info$="JPG13"

if seg_type=0xFE then seg_info$="COM"

print "segment (";hex$(seg_type);")",seg_info$,",length=",seg_length,",offset:",hex$(seg_start)

 

if seg_type=0xDD then print " -> restart interval=",jpeg_restart_interval

 

seg_start=seg_start+seg_length+2

return

 

2000 rem get huffman table

huff_table_count=0

while file_index<seg_start

  jpeg_huff_table_factor=asc(input$(1,#1))

  file_index=file_index+1

  jpeg_huff_table_index=jpeg_huff_table_factor and 0xf

  jpeg_huff_table_ac=int(jpeg_huff_table_factor/16)

  if jpeg_huff_table_ac=1 then jpeg_huff_table_type$="AC" else jpeg_huff_table_type$="DC"

  print " -> huffman table index=",jpeg_huff_table_index,",huffman table type:",jpeg_huff_table_type$

  huff_table_len=0

  huffman_index=0

  while eof(1)=0 and huffman_index<16

    a=asc(input$(1,#1))

    file_index=file_index+1

    huff_table_len=huff_table_len+a

    huffman_index=huffman_index+1

    huffman_group_len[jpeg_huff_table_index][jpeg_huff_table_ac][huffman_index]=a

  wend

  while eof(1)=0 and huffman_index<huff_table_len+16

    a=asc(input$(1,#1))

    file_index=file_index+1

    huffman_index=huffman_index+1

    huffman_table_value[jpeg_huff_table_index][jpeg_huff_table_ac][huffman_index-17]=a

  wend

  huff_count=0

  huff_code=0

  huff_code_len=1

  for i=1 to 16

    j=0

    while j<huffman_group_len[jpeg_huff_table_index][jpeg_huff_table_ac][i]

      while huff_code_len<i

        huff_code=huff_code*2

        huff_code_len=huff_code_len+1

      wend

      b$=right$("0000000000000000"+bin$(huff_code),i)

      huffman_table_code$[jpeg_huff_table_index][jpeg_huff_table_ac][huff_count]=b$

      huffman_table_code_len[jpeg_huff_table_index][jpeg_huff_table_ac][huff_count]=i

      if huff_count<8 then print huffman_table_value[jpeg_huff_table_index][jpeg_huff_table_ac][huff_count],"(";b$;")",;

      huff_count=huff_count+1

      huff_code=huff_code+1

      j=j+1

    wend

  next

  huffman_table_count[jpeg_huff_table_index][jpeg_huff_table_ac]=huff_count

  print ",total",huffman_index-16,",",huff_count,",end at",hex$(file_index)

  huff_table_count=huff_table_count+1

wend

return

 

3000 rem scan mcu data - dc

z_subset=(py_offset*component_info_hfactor[1]+px_offset)/compress_bits

for zy=1 to compress_bits

  for zx=1 to compress_bits

    DCT_ac_array[pixel_component][z_subset][zx][zy]=0

    DCT_ac_array_hit[pixel_component][z_subset][zx][zy]=0

  next

next

pixel_quant_table_selected=component_quant_table[pixel_component]

zz_count=0

assigned_index=component_huff_table_dc[pixel_component]

assigned_ac=0

if huffman_hit=1 and scan_count<scan_count_limit+1 then print " -> x offset",px_offset,",y offset",py_offset

if huffman_hit=1 and scan_count<scan_count_limit+1 then print " -> scan huffman dc table:",assigned_index

gosub 4000

gosub 4300

if huffman_value>0 then DCT_dc_value[pixel_component]=value_of_code+DCT_dc_value[pixel_component]

if huffman_hit=1 and scan_count<scan_count_limit+1 then print " -> table:",pixel_quant_table_selected

if huffman_hit=1 and scan_count<scan_count_limit+1 then print " -> dc_value",DCT_dc_value[pixel_component]

DCT_ac_array[pixel_component][z_subset][1][1]=DCT_dc_value[pixel_component]*jpeg_quant_table[pixel_quant_table_selected][0]*approximation_factor

DCT_ac_array_hit[pixel_component][z_subset][1][1]=1

return

 

3300 rem scan mcu data - ac

z_subset=(py_offset*component_info_hfactor[1]+px_offset)/compress_bits

if approximation_flag=1

then

  for zy=1 to compress_bits

    for zx=1 to compress_bits

      DCT_ac_array[pixel_component][z_subset][zx][zy]=0

      DCT_ac_array_hit[pixel_component][z_subset][zx][zy]=0

    next

  next

endif

pixel_quant_table_selected=component_quant_table[pixel_component]

zz_count=approximation_ac_start

assigned_index=component_huff_table_ac[pixel_component]

assigned_ac=1

if huffman_hit=1 and eob_run=0 and scan_count<scan_count_limit+1 then print " -> scan huffman ac table:",assigned_index,"from",approximation_ac_start,"to",approximation_ac_end

gosub 5300

if eob_flag=1 then return

while eof(1)=0 and eob_flag=0 and zz_count<=approximation_ac_end

  gosub 4000

  gosub 4300

  if huffman_hit=1 and huffman_size_val>0

  then

    zz_count=zz_count+RunLengthZeros

    zx=ZigZagArray_inv_x[zz_count]

    zy=ZigZagArray_inv_y[zz_count]

    DCT_ac_array[pixel_component][z_subset][zx][zy]=value_of_code*jpeg_quant_table[pixel_quant_table_selected][zz_count]*approximation_factor

    DCT_ac_array_hit[pixel_component][z_subset][zx][zy]=1

    zz_count=zz_count+1

  endif

  if huffman_hit=1 and huffman_size_val=0 and RunLengthZeros=0xf then zz_count=zz_count+16

  if huffman_hit=1 and huffman_size_val=0 and RunLengthZeros=0 then eob_run=0 : eob_flag=1

  if huffman_hit=1 and huffman_size_val=0 and RunLengthZeros<15 and RunLengthZeros>0

  then

    i=0

    eob_run=1

    while i<RunLengthZeros

      eob_run=eob_run*2

      i=i+1

    wend

    test_eob_run_flag=1

    huffman_size_val=RunLengthZeros

    gosub 4300

    eob_run=eob_run+value_of_code

    eob_run=eob_run-1

    eob_flag=1

  endif

  if eob_flag=1 and eob_run>0 and eob_run_found_count<scan_count_limit

  then

    print " -> eob run",eob_run,"times (x,y)=",graph_x_offset,",",graph_y_offset,",at",hex$(file_index)

    eob_run_found_count=eob_run_found_count+1

  endif

wend

if huffman_hit=1 and scan_count<scan_count_limit+1 then print " - EOB"

return

 

3600 rem inverse dct transform

z_subset=(py_offset*component_info_hfactor[1]+px_offset)/compress_bits

if pixel_component=1 then pixel_component_info$=" Y"

if pixel_component=2 then pixel_component_info$="Cb"

if pixel_component=3 then pixel_component_info$="Cr"

if eob_run=0 then p_ok_flag=0 else p_ok_flag=1

for py=1 to compress_bits

  for px=1 to compress_bits

    sum=0

    for zy=1 to compress_bits

      if p_ok_flag=0 and scan_count<scan_count_limit+1 then print " -> DCT",pixel_component_info$,"array [";z_subset;"]",;

      for zx=1 to compress_bits

        if DCT_ac_array_hit[pixel_component][z_subset][zx][zy]=1

        then

          a=DCT_ac_array[pixel_component][z_subset][zx][zy]*IDCT_table_ux[px][zx]*IDCT_table_vy[py][zy]

          sum=sum+a

        endif

        if p_ok_flag=0 and scan_count<scan_count_limit+1 then print right$(" "+str$(DCT_ac_array[pixel_component][z_subset][zx][zy]),5),;

      next

      if p_ok_flag=0 and scan_count<scan_count_limit+1 then print

    next

    sum=2*sum/compress_bits+128

    p_ok_flag=1

    pixel_array[pixel_component][px+px_offset][py+py_offset]=sum

  next

next

return

 

4000 rem decode huffman code

test_eob_run_flag=0

value_code$=""

value_of_code=0

huffman_value=0

RunLengthZeros=0

huffman_size_val=0

huffman_hit=1

if fetch_finish_flag=1 then return

huffman_code$=""

while eof(1)=0 and len(huffman_code$)<16 and fetch_finish_flag=0

  if remain_bits=0 and fetch_code_borrow_flag=0

  then

    fetch_code=asc(input$(1,#1))

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    file_index=file_index+1

    remain_bits=8

  endif

  if remain_bits=0 and fetch_code_borrow_flag=1

  then

    fetch_code=fetch_code_borrow

    fetch_code_borrow_flag=0

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    remain_bits=8

  endif

  if remain_bits=8 and fetch_code_keep=0xff and fetch_code=0

  then

    fetch_code=asc(input$(1,#1))

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    file_index=file_index+1

  endif

  if remain_bits=8 and fetch_code_keep=0xff and (fetch_code=0xda or fetch_code=0xc4) and approximation_flag=1

  then

    fetch_code_borrow=asc(input$(1,#1))

    fetch_code_borrow_flag=1

    file_index=file_index+1

  endif

  if remain_bits=8 and fetch_code_keep=0xff and (fetch_code=0xda or fetch_code=0xc4) and fetch_code_borrow=0 and approximation_flag=1

  then

    fetch_finish_type=fetch_code

    fetch_finish_flag=1

    fetch_code=0

  endif

  if remain_bits=8 then fetch_code_keep=fetch_code

  if (fetch_code and 0x80)=0 then huffman_code$=huffman_code$+"0" else huffman_code$=huffman_code$+"1"

  fetch_code=(fetch_code*2) and 0xff

  remain_bits=remain_bits-1

  gosub 5000

  if huffman_hit=1 then break

wend

RunLengthZeros=int(huffman_value/16)

huffman_size_val=huffman_value and 0xf

return

 

4300 rem get values

if fetch_finish_flag=1 then return

value_code$=""

value_of_code=0

sign_base=1

while eof(1)=0 and len(value_code$)<huffman_size_val and huffman_hit=1 and fetch_finish_flag=0

  if remain_bits=0 and fetch_code_borrow_flag=0

  then

    fetch_code=asc(input$(1,#1))

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    file_index=file_index+1

    remain_bits=8

  endif

  if remain_bits=0 and fetch_code_borrow_flag=1

  then

    fetch_code=fetch_code_borrow

    fetch_code_borrow_flag=0

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    remain_bits=8

  endif

  if remain_bits=8 and fetch_code_keep=0xff and fetch_code=0

  then

    fetch_code=asc(input$(1,#1))

    fetch_source$=fetch_source$+" "+right$("00000000"+bin$(fetch_code),8)+"("+hex$(fetch_code)+")"

    file_index=file_index+1

  endif

  if remain_bits=8 and fetch_code_keep=0xff and (fetch_code=0xda or fetch_code=0xc4) and approximation_flag=1

  then

    fetch_code_borrow=asc(input$(1,#1))

    fetch_code_borrow_flag=1

    file_index=file_index+1

  endif

  if remain_bits=8 and fetch_code_keep=0xff and (fetch_code=0xda or fetch_code=0xc4) and fetch_code_borrow=0 and approximation_flag=1

  then

    fetch_finish_flag=1

    fetch_code=0

  endif

  if remain_bits=8 then fetch_code_keep=fetch_code

  if (fetch_code and 0x80)=0

  then

    value_code$=value_code$+"0"

    value_of_code=value_of_code*2

  else

    value_code$=value_code$+"1"

    value_of_code=value_of_code*2+1

  endif

  sign_base=sign_base*2

  fetch_code=(fetch_code*2) and 0xff

  remain_bits=remain_bits-1

wend

if left$(value_code$,1)="0" and test_eob_run_flag=0 then value_of_code=value_of_code-sign_base+1

if assigned_ac=0 then assigned_ac_flag$="dc" else assigned_ac_flag$="ac"

if huffman_hit=1 and scan_count<scan_count_limit

then

  print " -> ",fetch_source$,"(table",assigned_index,assigned_ac_flag$,")",",code [",huffman_code$,"]=(",hex$(huffman_size_val),"bits)",value_code$;"B =",value_of_code,"from #";zz_count,",Run Length Zeros=",RunLengthZeros

endif

if huffman_hit=1

then

  fetch_source$=""

  scan_count=scan_count+1

else miss_count=miss_count+1

endif

if huffman_hit=0 and miss_count<scan_count_limit then print " -> missed","(table",assigned_index,assigned_ac_flag$,")",",code [",huffman_code$,"]",", at",hex$(file_index)

return

 

5000 rem compare huffman code

huffman_hit=0

huffman_value=0

for i=0 to huffman_table_count[assigned_index][assigned_ac]-1

  if huffman_code$=huffman_table_code$[assigned_index][assigned_ac][i]

  then

    huffman_hit=1

    huffman_value=huffman_table_value[assigned_index][assigned_ac][i]

  endif

next

return

 

5300 rem check eob

eob_flag=0

if eob_run>0

then

  eob_run=eob_run-1

  eob_flag=1

endif

return

 

6000 rem get quantization table

while file_index<seg_start

  jpeg_quantization=asc(input$(1,#1))

  file_index=file_index+1

  jpeg_quant_select=jpeg_quantization and 0xf

  jpeg_quant_precision=int(jpeg_quantization/16)

  jpeg_quant_count=0

  while jpeg_quant_count<64

    a=asc(input$(1,#1))

    file_index=file_index+1

    jpeg_quant_table[jpeg_quant_select][jpeg_quant_count]=a

    jpeg_quant_count=jpeg_quant_count+1

  wend

  print " -> table:",jpeg_quant_select,",precision:",jpeg_quant_precision,",total",jpeg_quant_count,",end at",hex$(file_index)

wend

return

 

7000 rem get start of frame table

compress_bits=asc(input$(1,#1))

file_index=file_index+1

jpeg_height=asc(input$(1,#1))*256+asc(input$(1,#1))

file_index=file_index+2

jpeg_width=asc(input$(1,#1))*256+asc(input$(1,#1))

file_index=file_index+2

jpeg_c_type=asc(input$(1,#1))

file_index=file_index+1

if jpeg_c_type=1 then jpeg_color_type$="grey"

if jpeg_c_type=3 then jpeg_color_type$="YCbCr"

if jpeg_c_type=4 then jpeg_color_type$="CMYK"

print " -> jpeg width=",jpeg_width,",jpeg height=",jpeg_height,",resolution=",compress_bits,"bits,type",jpeg_color_type$

 

jpeg_c_identifier=0

while file_index<seg_start

  jpeg_c_id=asc(input$(1,#1))

  jpeg_c_identifier=jpeg_c_identifier+1

  file_index=file_index+1

  jpeg_c_sample_factor=asc(input$(1,#1))

  file_index=file_index+1

  jpeg_c_vfactor=jpeg_c_sample_factor and 0xf

  jpeg_c_hfactor=int(jpeg_c_sample_factor/16)

  jpeg_c_table=asc(input$(1,#1))

  file_index=file_index+1

  component_info_id_pointer[jpeg_c_id]=jpeg_c_identifier

  component_info_vfactor[jpeg_c_identifier]=jpeg_c_vfactor

  component_info_hfactor[jpeg_c_identifier]=jpeg_c_hfactor

  component_quant_table[jpeg_c_identifier]=jpeg_c_table

  print " -> component id:",jpeg_c_id,",h_factor:",jpeg_c_hfactor,",v_factor:",jpeg_c_vfactor,",table:",jpeg_c_table

wend

zx=1

zy=1

zz_count=0

zz_direct=0

ZigZagArray[zx][zy]=zz_count

ZigZagArray_inv_x[zz_count]=zx

ZigZagArray_inv_y[zz_count]=zy

zz_count=zz_count+1

while zz_count<=compress_bits*compress_bits

  shift_flag=0

  if zz_direct=0 and zy=1 then zx=zx+1 : zz_direct=1 : shift_flag=1

  if zz_direct=0 and zx=compress_bits then zy=zy+1 : zz_direct=1 : shift_flag=1

  if zz_direct=1 and zx=1 then zy=zy+1 : zz_direct=0 : shift_flag=1

  if zz_direct=1 and zy=compress_bits then zx=zx+1 : zz_direct=0 : shift_flag=1

  if zx=1 and zy>compress_bits then zx=2 : zy=compress_bits

  if zy=1 and zx>compress_bits then zy=2 : zx=compress_bits

  if zz_direct=0 and shift_flag=0 then zx=zx+1 : zy=zy-1

  if zz_direct=1 and shift_flag=0 then zx=zx-1 : zy=zy+1

  ZigZagArray[zx][zy]=zz_count

  ZigZagArray_inv_x[zz_count]=zx

  ZigZagArray_inv_y[zz_count]=zy

  zz_count=zz_count+1

wend

print " -> Zig Zag Array"

print " -> ",;

for zy=1 to compress_bits

  for zx=1 to compress_bits

    print right$(" "+str$(ZigZagArray[zx][zy]),3),;

  next

  print

  if zy<compress_bits then print " -> ",;

next

v_pi=3.141592654

for px=1 to compress_bits

  for zx=1 to compress_bits

    if zx=1 then cx=1/sqr(2) else cx=1

    IDCT_table_ux[px][zx]=cx*cos(((2*px-1)*(zx-1)*v_pi)/(compress_bits*2))

  next

next

for py=1 to compress_bits

  for zy=1 to compress_bits

    if zy=1 then cy=1/sqr(2) else cy=1

    IDCT_table_vy[py][zy]=cy*cos(((2*py-1)*(zy-1)*v_pi)/(compress_bits*2))

  next

next

return

 

8000 rem read start of scan header information

jpeg_scan_compnents=asc(input$(1,#1))

file_index=file_index+1

for i=1 to jpeg_scan_compnents

  jpeg_scan_comp_index=asc(input$(1,#1))

  file_index=file_index+1

  jpeg_scan_comp_huff_table=asc(input$(1,#1))

  file_index=file_index+1

  jpeg_scan_comp_huff_table_ac=jpeg_scan_comp_huff_table and 0xf

  jpeg_scan_comp_huff_table_dc=int(jpeg_scan_comp_huff_table/16)

  t_pointer=component_info_id_pointer[jpeg_scan_comp_index]

  jpeg_scan_comp_elements[i]=t_pointer

  component_huff_table_ac[t_pointer]=jpeg_scan_comp_huff_table_ac

  component_huff_table_dc[t_pointer]=jpeg_scan_comp_huff_table_dc

  print " -> component id:",jpeg_scan_comp_index,",dc table:",jpeg_scan_comp_huff_table_dc,",ac table:",jpeg_scan_comp_huff_table_ac

next

dct_scan_start=asc(input$(1,#1))

file_index=file_index+1

dct_scan_end=asc(input$(1,#1))

file_index=file_index+1

approximation=asc(input$(1,#1))

file_index=file_index+1

print " -> scan from",dct_scan_start,"to",dct_scan_end,",approximation",hex$(approximation)

if dct_scan_start=0 and dct_scan_end=compress_bits*compress_bits-1 and approximation=0 then approximation_flag=0 else approximation_flag=1

i=0

approximation_factor=1

while i<(approximation and 0xf)

  approximation_factor=approximation_factor*2

  i=i+1

wend

jpeg_mcu_count=0

remain_bits=0

fetch_source$=""

eob_run=0

fetch_escape_flag=0

fetch_finish_flag=0

fetch_code_borrow_flag=0

DCT_dc_value[1]=0

DCT_dc_value[2]=0

DCT_dc_value[3]=0

if small_mode=1 then graph_index_limit=8000 else graph_index_limit=6000

scan_count_limit=10

scan_count=0

eob_run_found_count=0

for pixel_component=1 to 3

  dct_scan_end_keep[pixel_component]=0

  for z_subset=0 to 3

    for zy=1 to compress_bits

      for zx=1 to compress_bits

        DCT_ac_array[pixel_component][z_subset][zx][zy]=0

        DCT_ac_array_hit[pixel_component][z_subset][zx][zy]=0

      next

    next

  next

  for zy=1 to compress_bits*component_info_vfactor[1]

    for zx=1 to compress_bits*component_info_hfactor[1]

      pixel_array[pixel_component][zx][zy]=128

    next

  next

next

hfactor[2]=component_info_hfactor[2]/component_info_hfactor[1]

hfactor[3]=component_info_hfactor[3]/component_info_hfactor[1]

vfactor[2]=component_info_vfactor[2]/component_info_vfactor[1]

vfactor[3]=component_info_vfactor[3]/component_info_vfactor[1]

jpeg_restart_count=0

graph_index=0

return

 

9000 rem process huffman decoding

gosub 8000

 

print " -> decode at:",hex$(file_index)

graph_y_offset=0

while graph_y_offset<jpeg_height and eof(1)=0

  graph_x_offset=0

  while graph_x_offset<jpeg_width and eof(1)=0

    if jpeg_restart_flag=1 and jpeg_restart_count>=jpeg_restart_interval and fetch_code_borrow_flag=1

    then

      a=0xff

      b=asc(input$(1,#1))

      file_index=file_index+1

    else a=1

    endif

    if jpeg_restart_flag=1 and jpeg_restart_count>=jpeg_restart_interval and fetch_code_borrow_flag=0

    then

      a=asc(input$(1,#1))

      file_index=file_index+1

      b=asc(input$(1,#1))

      file_index=file_index+1

    else a=1

    endif

    if a=0 and fetch_code_keep=0xff and b=0xff

    then

      a=0xff

      b=asc(input$(1,#1))

      file_index=file_index+1

    endif

    if a=0xff and jpeg_restart_flag=1 and jpeg_restart_count>=jpeg_restart_interval

    then

      print " -> RST tag",(b and 0xf),"found (x,y)=",graph_x_offset,",",graph_y_offset,", at",hex$(file_index-2),"remain",remain_bits,"bits"

      remain_bits=0

      fetch_code_borrow_flag=0

      fetch_code_keep=0

      DCT_dc_value[1]=0

      DCT_dc_value[2]=0

      DCT_dc_value[3]=0

      jpeg_restart_count=0

    endif

    if a<>0xff and jpeg_restart_flag=1 and jpeg_restart_count>=jpeg_restart_interval

    then

      print " -> Miss RST tag ,at",hex$(file_index-2)

    endif

      

    rem baseline scan

    if approximation_flag=0

    then

      approximation_factor=1

      approximation_ac_start=1

      approximation_ac_end=dct_scan_end

      pixel_component=1

      for p_vfactor=1 to component_info_vfactor[1]

        py_offset=compress_bits*(p_vfactor-1)

        for p_hfactor=1 to component_info_hfactor[1]

          px_offset=compress_bits*(p_hfactor-1)

          gosub 3000

          gosub 3300

        next

      next

      px_offset=0

      py_offset=0

      pixel_component=2

      gosub 3000

      gosub 3300

      pixel_component=3

      gosub 3000

      gosub 3300

      pixel_component=1

      for p_vfactor=1 to component_info_vfactor[1]

        py_offset=compress_bits*(p_vfactor-1)

        for p_hfactor=1 to component_info_hfactor[1]

          px_offset=compress_bits*(p_hfactor-1)

          gosub 3600

        next

      next

      px_offset=0

      py_offset=0

      pixel_component=2

      gosub 3600

      pixel_component=3

      gosub 3600

    endif

      

    rem none successive approximation

    jpeg_scan_comp_index=1

    while jpeg_scan_comp_index<=jpeg_scan_compnents and approximation_flag=1 and (approximation and 0xf0)=0

      approximation_ac_start=dct_scan_start

      approximation_ac_end=dct_scan_end

      pixel_component=jpeg_scan_comp_elements[jpeg_scan_comp_index]

      dct_scan_end_keep[pixel_component]=dct_scan_end

      for p_vfactor=1 to component_info_vfactor[1]

        py_offset=compress_bits*(p_vfactor-1)

        for p_hfactor=1 to component_info_hfactor[1]

          px_offset=compress_bits*(p_hfactor-1)

          if pixel_component=1 and dct_scan_end=0 then gosub 3000

          if pixel_component=1 and dct_scan_end>0 then gosub 3300

          if pixel_component=1 then gosub 3600

        next

      next

      px_offset=0

      py_offset=0

      if pixel_component=2 and dct_scan_end=0 then gosub 3000

      if pixel_component=2 and dct_scan_end>0 then gosub 3300

      if pixel_component=2 then gosub 3600

      if pixel_component=3 and dct_scan_end=0 then gosub 3000

      if pixel_component=3 and dct_scan_end>0 then gosub 3300

      if pixel_component=3 then gosub 3600

      jpeg_scan_comp_index=jpeg_scan_comp_index+1

    wend

      

    if approximation_flag=1 and (approximation and 0xf0)<>0 then break

      

    jpeg_mcu_count=jpeg_mcu_count+1

    jpeg_restart_count=jpeg_restart_count+1

      

    comp_ivf1=component_info_vfactor[1]

    comp_ihf1=component_info_hfactor[1]

    for graph_y_sec_out=1 to component_info_vfactor[1]

      graph_y_sec_offset=(graph_y_sec_out-1)*compress_bits

      for graph_x_sec_out=1 to component_info_hfactor[1]

        graph_x_sec_offset=(graph_x_sec_out-1)*compress_bits

        if approximation_flag=1 and graph_index<graph_index_limit

        then

          color_source_low$=color_block_low$[graph_index]

          color_source_high$=color_block_high$[graph_index]

        else

          color_source_low$=""

          color_source_high$=""

        endif

        color_dest_low$=""

        color_dest_high$=""

        for graph_y_sec_in=1 to compress_bits

          graph_y=graph_y_sec_offset+graph_y_sec_in

          for graph_x_sec_in=1 to compress_bits

            graph_x=graph_x_sec_offset+graph_x_sec_in

            color_Y=pixel_array[1][graph_x][graph_y]

            color_Cb=pixel_array[2][int((graph_x-1)*hfactor[2]+1)][int((graph_y-1)*vfactor[2]+1)]

            color_Cr=pixel_array[3][int((graph_x-1)*hfactor[3]+1)][int((graph_y-1)*vfactor[3]+1)]

            color_red=color_Y+1.402*(color_Cr-128)

            color_green=color_Y-0.34414*(color_Cb-128)-0.71414*(color_Cr-128)

            color_blue=color_Y+1.772*(color_Cb-128)

            if huffman_hit=1 and eob_run=0 and scan_count<scan_count_limit+1 then print "(",color_red,color_green,color_blue,")",;

            if small_mode=1 and (graph_x mod 2)=1 and (graph_y mod 2)=1

            then

              i=((graph_y_sec_in-1)*compress_bits/4+(graph_x_sec_in-1)/2)*2

            else

              i=((graph_y_sec_in-1)*compress_bits+(graph_x_sec_in-1))*2

            endif

            if start_of_scan_count>0 and approximation_flag=1 and (((graph_x mod 2)=1 and (graph_y mod 2)=1) or small_mode=0)

            then

              color_val_4=asc(mid$(color_source_low$,i+1,2))

              color_val_5=asc(mid$(color_source_high$,i+1,2))

              color_val_1=color_val_4 and 0x3ff

              color_val_2=(int(color_val_5*0x40)+int(color_val_4/0x400)) and 0x3ff

              color_val_3=int(color_val_5/0x10) and 0x3ff

              color_red=color_red+(color_val_1-256)

              color_green=color_green+(color_val_2-256)

              color_blue=color_blue+(color_val_3-256)

            endif

            if approximation_flag=1 and (((graph_x mod 2)=1 and (graph_y mod 2)=1) or small_mode=0)

            then

              color_val_1=(color_red+128) and 0x3ff

              color_val_2=(color_green+128) and 0x3ff

              color_val_3=(color_blue+128) and 0x3ff

              color_val_4=int((color_val_2 mod 0x40)*0x400+color_val_1) and 0xffff

              color_val_5=int(color_val_3*0x10+color_val_2/0x40) and 0xffff

              low=int(color_val_4) and 0xff

              high=int(color_val_5) and 0xff

              color_low$=chr$(low)

              color_high$=chr$(high)

              color_dest_low$=color_dest_low$+color_low$

              color_dest_high$=color_dest_high$+color_high$

              low=int(color_val_4/256) and 0xff

              high=int(color_val_5/256) and 0xff

              color_low$=chr$(low)

              color_high$=chr$(high)

              color_dest_low$=color_dest_low$+color_low$

              color_dest_high$=color_dest_high$+color_high$

            endif

            if color_red<0 then color_red=0

            if color_green<0 then color_green=0

            if color_blue<0 then color_blue=0

            if color_red>255 then color_red=255

            if color_green>255 then color_green=255

            if color_blue>255 then color_blue=255

            color (color_red,color_green,color_blue)

            if small_mode=0

            then

              x=(graph_x+graph_x_offset)+100

              y=500-(graph_y+graph_y_offset)

            else

              x=int((graph_x+graph_x_offset)/2)+100

              y=500-int((graph_y+graph_y_offset)/2)

            endif

            if small_mode=0 and graph_x+graph_x_offset<=jpeg_width and graph_y+graph_y_offset<=jpeg_height then point (x,y)

            if small_mode=1 and graph_x+graph_x_offset<=jpeg_width and graph_y+graph_y_offset<=jpeg_height and (graph_x mod 2)=1 and (graph_y mod 2)=1 then point (x,y)

          next

          if huffman_hit=1 and eob_run=0 and scan_count<scan_count_limit+1 then print

        next

        if approximation_flag=1 and graph_index<graph_index_limit

        then

          color_block_low$[graph_index]=color_dest_low$

          color_block_high$[graph_index]=color_dest_high$

        endif

        graph_index=graph_index+1

      next

    next

      

    graph_x_offset=graph_x_offset+compress_bits*component_info_hfactor[1]

    if fetch_finish_flag=1

    then

      seg_start=file_index-3

      print

      print " -> found ",hex$(fetch_finish_type),"head at",hex$(seg_start),"(x,y)=",graph_x_offset,",",graph_y_offset,",",miss_count,"missed",",total",jpeg_mcu_count,"mcu blocks scaned"

      scan_count=0

    endif

    if fetch_finish_flag=1 and graph_y_offset+compress_bits*component_info_vfactor[1]<jpeg_height

    then

      gosub 1000

      gosub 8000

      fetch_finish_flag=0

    endif

    if fetch_finish_flag=1 and graph_y_offset+compress_bits*component_info_vfactor[1]>=jpeg_height

    then

      break

    endif

  wend

  graph_y_offset=graph_y_offset+compress_bits*component_info_vfactor[1]

  if y<=compress_bits*component_info_vfactor[1] and approximation_flag=0

  then

    screen

    jpeg_height=jpeg_height-graph_y_offset

    graph_y_offset=0

  endif

wend

print "Fetch code remains",remain_bits,"bits",fetch_source$

start_of_scan_count=start_of_scan_count+1

print "total",scan_count,"huffman codes scaned , end at",hex$(file_index),",",miss_count,"missed",",total",jpeg_mcu_count,"mcu blocks scaned"

if miss_count=0 or approximation_flag=1 then seg_start=file_index else break_flag=1

seg_type=0

return