remiq/qr_code

encode fails for longer strings

gutschilla opened this issue · 1 comments

Hi, I encountered an issue when using this with longer strings as input. While this works:

iex(25)> QRCode.encode("12345678901234") 
%QRCode{
  data: <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 51, 248, 4, 18, 80,
    64, 46, 180, 186, 1, 117, 245, 208, 11, 174, 174, 128, 65, 85, 4, 3, 250,
    175, 224, 0, 25, 0, 0, 190, 91, 224, 7, 42, ...>>,
  dimension: 29,
  ecc: 'M',
  version: 1
}

This fails (under Elixir 1.8.1)

iex(26)> QRCode.encode("123456789012345")
** (FunctionClauseError) no function clause matching in QRCode.Matrix.embed_data/3    
    
    The following arguments were given to QRCode.Matrix.embed_data/3:
    
        # 1
        []
    
        # 2
        <<0>>
    
        # 3
        [
          [:f, :f, :f, :f, :f, :f, :f, :f, 0, 0, 0, 1, 0, 0, 1, 1, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, 0, 1, 1, 0, 1, 1, 0, 1, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, 1, 0, 0, 0, 1, 0, 0, 1, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, 1, 0, 1, 0, 1, 0, 1, 0, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, :a, 1, 0, 0, 0, 1, 0, 0, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, :a, 0, 0, 0, 0, 1, 0, 0, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, :a, :t, :t, :t, :t, :t, :t, :t, :t, :f, :f,
           :f, :f, :f, :f, :f, :f],
          [:f, :f, :f, :f, :f, :f, :f, :f, :a, 0, 1, 0, 0, 1, 1, 0, :m, :f, :f, :f, :f,
           :f, :f, :f, :f],
          [:m, :m, :m, :m, :m, :m, :m, :m, :a, 1, 1, 1, 0, 0, 1, 1, :m, :m, :t, :m, :m,
           :m, :m, :m, :m],
          [1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, :t, 1, 1, 0, 1, 0, 0],
          [0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, :t, 0, 1, 0, 0, 0, 0],
          [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, :t, 1, 0, 1, 1, 1, 1],
          [1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, :t, 1, 1, 1, 0, 1, 0],
          [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, :t, 0, 1, 1, 1, 0, 0],
          [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, :t, 1, 0, 1, 1, 0, 1],
          [0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, :t, 1, 1, 1, 0, 0, 0],
          [0, 1, 0, 1, :a, :a, :a, :a, :a, 1, 0, 0, 1, 1, 1, 0, :a, :a, :a, :a, :a, 0,
           1, 0, 0],
          [0, 0, 1, 0, :a, :a, :a, :a, :a, 1, 0, 1, 0, 0, 0, 1, :m, :f, :f, :f, :f, :f,
           :f, :f, :f],
          [1, 0, 1, 0, :a, :a, :a, :a, :a, 0, 0, 1, 0, 0, 0, 1, :m, :f, :f, :f, :f, :f,
           :f, :f, :f],
          [1, 1, 0, 1, :a, :a, :a, :a, :a, 0, 0, 0, 1, 0, 1, 0, :m, :f, :f, :f, :f, :f,
           :f, :f, :f],
          [0, 1, 0, 1, :a, :a, :a, :a, :a, 1, 0, 0, 1, 1, 0, 0, :m, :f, :f, :f, :f, :f,
           :f, :f, :f],
          [1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, :m, :f, :f, :f, :f, :f, :f,
           :f, :f],
          [1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, :m, :f, :f, :f, :f, :f, :f,
           :f, :f],
          [1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, :m, :f, :f, :f, :f, :f, :f,
           :f, :f],
          [0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, :m, :f, :f, :f, :f, :f, :f,
           :f, :f]
        ]
    
    Attempted function clauses (showing 3 out of 3):
    
        defp embed_data([ha, hb, h, hc, hd | t], codewords, acc) when length(t) == 4
        defp embed_data([ha, hb, hc, hd | t], codewords, acc)
        defp embed_data([], <<>>, acc)
    
    (qr_code) lib/matrix.ex:83: QRCode.Matrix.embed_data/3
    (qr_code) lib/matrix.ex:19: QRCode.Matrix.embed_data/2
    (qr_code) lib/qr_code.ex:37: QRCode.encode/2

I found this module pretty neat since it doesn't use Rust as qr_coder does. Any idea? Thanks a lot! I am building an SVG module around it and stumbled over this once using strings longer thatn the usual "foobar".