def embed_or_extract(algorithm, filename, destfilename, message, para, embed):
    """This function gets as parameters
    filename ... the input file name
    destfilename ... the output filen ame
    message ... the message
    para ... the parameter for the chosen algorithm
    embed ... boolean: if True, we embed, else we extract.
    If embed is True it uses libstego to embed the given message
    in the given output file, calling the <algorithm>_embed()
    function in libstego.
    If embed is False, it uses libstego to extract a message
    from the given file, calling the <algorithm>_extract()
    function in libstego.
    This function can therefor be called recursively to check
    if embedding a message worked by calling it with embed=False.
    """
    ending = filename[-3:]
    print ending
    if embed:
        msglen = len(message) + 1
    else:
        message = libstego.new_charp()
        msglen = libstego.new_intp()
    if ending == "gif":
        src_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()
        libstegofile.io_gif_read(filename, src_data, gif_int)
        if algorithm == "Sort / Unsort":
            if embed:
                libstego.sortunsort_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.sortunsort_extract(src_data, message, msglen, para)
        elif algorithm == "GifShuffle":
            if embed:
                if para.method == 1:
                    pw_message = para.password
                    pw_message_len = para.pwlen
                    para.password = ""
                    para.pwlen = 0
                    pwmsg_data = libstegofile.palette_data_t()
                    para.method = 0
                    libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message, pw_message_len, para)
                    para.method = 1
                    libstego.gifshuffle_embed(pwmsg_data, stego_data, message, msglen, para)
                else:
                    print "normal gifshuffle:"
                    print "pw: " + para.password
                    print "pwlen: " + str(para.pwlen)
                    libstego.gifshuffle_embed(src_data, stego_data, message, msglen, para)
            else:
                if para.method == 1:
                    pw_message = para.password
                    pw_message_len = para.pwlen
                    para.password = ""
                    para.pwlen = 0
                    pwmsg_data = libstegofile.palette_data_t()
                    para.method = 0
                    libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message, pw_message_len, para)
                    para.adv_pal = pwmsg_data
                    para.method = 1
                    libstego.gifshuffle_extract(src_data, message, msglen, para)
                else:
                    libstego.gifshuffle_extract(src_data, message, msglen, para)

        elif algorithm == "Frirui":
            if embed:
                libstego.frirui_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.frirui_extract(src_data, message, msglen, para)
        if embed:
            print "integrate and write ..."
            libstegofile.io_gif_integrate(gif_int, stego_data)
            libstegofile.io_gif_write(destfilename, gif_int)
        # libstegofile.io_gif_cleanup_data(stego_data)
        # libstegofile.io_gif_cleanup_data(src_data)
        # libstegofile.io_gif_cleanup_internal(gif_int)
    elif ending == "png":
        src_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()
        libstegofile.io_png_read(filename, src_data, png_int)
        if algorithm == "Battlesteg":
            if embed:
                libstego.battlesteg_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.battlesteg_extract(src_data, message, msglen, para)

        elif algorithm == "CPT":
            if embed:
                libstego.cpt_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.cpt_extract(src_data, message, msglen, para)

        elif algorithm == "LSB":
            bytes = libstego.new_charpp()
            num_bytes = libstego.new_intp()
            stego_data = src_data
            libstego.lsb_convert_png(stego_data, bytes, num_bytes)
            if embed:
                ret = libstego.lsb_embed_indirect(
                    libstego.charpp_value(bytes), libstego.intp_value(num_bytes), message, msglen, para
                )
                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False
            else:
                ret = libstego.lsb_extract_indirect(
                    libstego.charpp_value(bytes), libstego.intp_value(num_bytes), message, msglen, para
                )
                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

            libstego.lsb_cleanup_converted_data(libstego.charpp_value(bytes))
            libstego.delete_charpp(bytes)

        if embed:
            libstegofile.io_png_integrate(png_int, stego_data)
            libstegofile.io_png_write(destfilename, png_int)
            libstegofile.io_png_cleanup_data(stego_data)
        # png cleanup ruft segmentation faults hervor...
        # libstegofile.io_png_cleanup_data(src_data)
        # libstegofile.io_png_cleanup_internal(png_int)

    elif ending == "svg":
        src_data = libstegofile.svg_data_t()
        stego_data = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()
        libstegofile.io_svg_read(filename, src_data, svg_int)
        if algorithm == "SVG Steg":
            if embed:
                ret = libstego.svg_embed(src_data, stego_data, message, msglen, para)

                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

            else:
                ret = libstego.svg_extract(src_data, message, msglen, para)

                if ret != 0:
                    print "An error occured. Error code: " + ` libstego.cvar.lstg_errno `
                    return False

        if embed:
            libstegofile.io_svg_integrate(svg_int, stego_data)
            libstegofile.io_svg_write(destfilename, svg_int)
            libstegofile.io_svg_cleanup_data(stego_data)

        libstegofile.io_svg_cleanup_data(src_data)
        libstegofile.io_svg_cleanup_internal(svg_int)

    elif ending == "wav":
        src_data = libstegofile.wav_data_t()
        stego_data = libstegofile.wav_data_t()
        wav_int = libstegofile.wav_internal_data_t()
        libstegofile.io_wav_read(filename, src_data, svg_int)
        if algorithm == "Echo Hiding":
            if embed:
                libstego.echohiding_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.echohiding_extract(src_data, message, msglen, para)
        elif algorithm == "Phase Coding":
            if embed:
                libstego.phasecoding_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.phasecoding_extract(src_data, message, msglen, para)
        libstegofile.io_wav_integrate(wav_int, stego_data)
        libstegofile.io_wav_write(destfilename, wav_int)
        libstegofile.io_wav_cleanup_data(stego_data)
        libstegofile.io_wav_cleanup_data(src_data)
        libstegofile.io_wav_cleanup_internal(wav_int)
    elif ending == "jpg" or "peg":
        src_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpg_int = libstegofile.jpeg_internal_data_t()
        libstegofile.io_jpeg_read(filename, src_data, jpg_int)
        if algorithm == "F5":
            if embed:
                libstego.f5_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.f5_extract(src_data, message, msglen, para)
        elif algorithm == "MB2":
            if embed:
                libstego.mb2_embed(src_data, stego_data, message, msglen, para)
            else:
                libstego.mb2_extract(src_data, message, msglen, para)
        libstegofile.io_jpeg_integrate(jpg_int, stego_data)
        libstegofile.io_jpeg_write(destfilename, jpg_int)
        # libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_data(src_data)
        libstegofile.io_jpeg_cleanup_internal(jpg_int)
    # TODO: extract for testing purpose!
    if embed:
        return True
    else:
        new_message = str(libstego.charp_value(message))
        length = libstego.intp_value(msglen)
        print new_message
        return new_message
def get_capacity(algorithm, filename, para):
    """This function gets parameters
    algorithm ... the String naming the chosen algorithm
    filename ... the chosen input filename
    para ... a parameter for the chosen algorithm
    and computes the capacity of the algorithm for the
    given file and parameters.
    It returns the capacity.
    """
    if filename[-3:] == "gif":
        palette_data = libstegofile.palette_data_t()
        gif_struct = libstegofile.gif_internal_data_t()
        bla = libstegofile.io_gif_read(filename, palette_data, gif_struct)
        if algorithm == "Frirui":
            cap = libstego.frirui_check_capacity(palette_data, para)
        elif algorithm == "GifShuffle":
            cap = libstego.gifshuffle_check_capacity(palette_data, para)
        elif algorithm == "Sort / Unsort":
            cap = libstego.sortunsort_check_capacity(palette_data, para)
        libstegofile.io_gif_cleanup_data(palette_data)
        # libstegofile.io_gif_cleanup_internal(gif_struct)

    elif filename[-3:] == "png":
        rgb_data = libstegofile.rgb_data_t()
        rgb_internal = libstegofile.png_internal_data_t()
        bla = libstegofile.io_png_read(filename, rgb_data, rgb_internal)
        if algorithm == "Battlesteg":
            cap = libstego.battlesteg_check_capacity(rgb_data, para)
        elif algorithm == "CPT":
            cap = libstego.cpt_check_capacity(rgb_data, para)
        elif algorithm == "LSB":
            bytes = libstego.new_charpp()
            num_bytes = libstego.new_intp()
            libstego.lsb_convert_png(rgb_data, bytes, num_bytes)
            cap = libstego.lsb_check_capacity_indirect(
                libstego.charpp_value(bytes), libstego.intp_value(num_bytes), para
            )
            libstego.lsb_cleanup_converted_data(libstego.charpp_value(bytes))
            libstego.delete_charpp(bytes)

    elif filename[-3:] == "wav":
        wav_data = wav_data_t()
        wav_int = wav_internal_data_t()
        bla = libstegofile.io_wav_read(filename, wav_data, wav_int)
        if algorithm == "Echo Hiding":
            cap = libstego.echohiding_check_capacity(wav_data, para)
        elif algorithm == "Phase Coding":
            cap = libstego.phasecoding_check_capacity(wav_data, para)
        elif algorithm == "PW":
            cap = libstego.pw_check_capacity(wav_data, para)

    elif filename[-3:] == "svg":
        svg_data = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()
        bla = libstegofile.io_svg_read(filename, svg_data, svg_int)
        if algorithm == "SVG Steg":
            cap = libstego.svg_check_capacity(svg_data, para)

    elif filename[-3:] in ["peg", "jpg"]:
        jpeg_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()
        bla = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if algorithm == "F5":
            cap = libstego.f5_check_capacity(jpeg_data, para)
        elif algorithm == "MB2":
            cap = libstego.mb2_check_capacity(jpeg_data, para)
        elif algorithm == "PQ":
            cap = libstego.pq_check_capacity(jpeg_data, para)

    elif algorithm == "LSB":
        cap = libstego.lsb_check_capacity(palette_data, para)
    print cap
    if cap[0] == 0:
        return cap[1]
    else:
        print "Error computing capacity!"
        return 666
def embed_or_extract_with_method(embed, method, filename, destfilename, message, msglen):
    if embed:
        print "embedding with method " + `method+1` + ", algo: " + method_to_algo[method]
    else:
        p_message = libstego.new_charp()
        p_msglen = libstego.new_intp()
        print "extracting with method " + `method+1` + ", algo: " + method_to_algo[method]

    if method_to_algo[method] == "PQ":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return

        para = methods[method]
        if embed:
            err = libstego.pq_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpeg_int, stego_data)
                if err != 0:
                    print "Error while integrating JPEG"
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
                if err != 0:
                    print "Error while writing JPEG"
            else:
                print "An error occured while embedding with PQ."
        else:
            err = libstego.pq_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "An error occured while extracting with PQ."

        # cleanup
        libstegofile.io_jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "F5":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return


        para = methods[method]
        if embed:
            err = libstego.f5_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
            else:
                print "Error while embedding with F5."
        else:
            err = libstego.f5_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with F5."

        # cleanup
        libstegofile.jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "Adv. Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.method = 1
            err = libstego.gifshuffle_embed(pwmsg_data, stego_data,
                    message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.adv_pal = pwmsg_data
            para.method = 1
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.gifshuffle_embed(palette_data, stego_data, message, msglen, para)
            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Frirui":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.frirui_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.frirui_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Sort/Unsort":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            libstego.sortunsort_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            libstego.sortunsort_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)

    elif method_to_algo[method] == "CPT":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            print(para.password)
            print(para.pwlen)
            print(para.block_width)
            print(para.block_height)
            err = libstego.cpt_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.cpt_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)

    elif method_to_algo[method] == "Battlesteg":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            err = libstego.battlesteg_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.battlesteg_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)


    elif method_to_algo[method] == "SVG Steg":
        # prepare data strucures
        svg_data = libstegofile.svg_data_t()
        svg_stego = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()

        # read file data
        err = libstegofile.io_svg_read(filename, svg_data, svg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading SVG"
            return

        para = methods[method]
        if embed:
            err = libstego.svg_embed(svg_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_svg_integrate(svg_int, stego_data)
                if err != 0:
                    print "Error while integrating SVG"
                err = libstegofile.io_svg_write(destfilename, svg_int)
                if err != 0:
                    print "Error while writing SVG"
            else:
                print "Error while embedding with SVG Stego"
        else:
            err = libstego.svg_extract(svg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with SVG Stego"

        # cleanup
        libstegofile.svg_cleanup_data(svg_data)
        libstegofile.svg_cleanup_data(stego_data)
        libstegofile.svg_cleanup_internal(svg_int)

    elif method_to_algo[method] == "Echo Hiding":
        # prepare data strucures
        wav_data = libstegofile.wav_data_t()
        stego_data = libstegofile.wav_data_t()
        wav_int = libstegofile.wav_internal_data_t()

        # read file data
        err = libstegofile.io_wav_read(filename, wav_data, wav_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading WAV"
            return

        para = methods[method]
        if embed:
            err = libstego.eh_embed(wav_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_wav_integrate(wav_int, stego_data)
                if err != 0:
                    print "Error while integrating WAV"
                err = libstegofile.io_wav_write(destfilename, wav_int)
                if err != 0:
                    print "Error while writing WAV"
            else:
                print "Error while embedding with Echo Hiding"
        else:
            err = libstego.eh_extract(wav_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with Echo Hiding"

        # cleanup
        libstegofile.wav_cleanup_data(wav_data)
        libstegofile.wav_cleanup_data(stego_data)
        libstegofile.wav_cleanup_internal(wav_int)


    elif method_to_algo[method] == "Phase Coding":
        # TODO implement
        pass


    elif method_to_algo[method] == "LSB":
        # TODO implement
        pass

    if embed:
        return None
    else:
        message = str(libstego.charp_value(p_message))
        print message
        msglen = libstego.intp_value(p_msglen)
        return message
def get_best_method(filename, msglen):
    global num_methods
    global method_to_algo
    global methods

    for method in range(0, num_methods):
        fits = False
        para = methods[method]
        print "Testing method " + `method+1`
        print "Algorithm: " + method_to_algo[method]

        if method_to_algo[method] == "PQ":
            # prepare data strucures
            jpeg_data = libstegofile.jpeg_data_t()
            jpeg_int = libstegofile.jpeg_internal_data_t()

            # read file data
            err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.pq_check_capacity(jpeg_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


        elif method_to_algo[method] == "F5":
            # prepare data strucures
            jpeg_data = libstegofile.jpeg_data_t()
            jpeg_int = libstegofile.jpeg_internal_data_t()

            # read file data
            err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.f5_check_capacity(jpeg_data) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


        elif method_to_algo[method] in ["Adv. Gifshuffle", "Gifshuffle"]:
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.gifshuffle_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)


        elif method_to_algo[method] == "Frirui":
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.frirui_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)


        elif method_to_algo[method] == "Sort/Unsort":
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.sortunsort_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)

        elif method_to_algo[method] == "CPT":
            # prepare data strucures
            rgb_data = libstegofile.rgb_data_t()
            png_int = libstegofile.png_internal_data_t()

            # read file data
            err = libstegofile.io_png_read(filename, rgb_data, png_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.cpt_check_capacity(rgb_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_png_cleanup_data(rgb_data)
            libstegofile.io_png_cleanup_internal(png_int)


        elif method_to_algo[method] == "Battlesteg":
            # prepare data strucures
            rgb_data = libstegofile.rgb_data_t()
            png_int = libstegofile.png_internal_data_t()

            # read file data
            err = libstegofile.io_png_read(filename, rgb_data, png_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.battlesteg_check_capacity(rgb_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_png_cleanup_data(rgb_data)
            libstegofile.io_png_cleanup_internal(png_int)


        elif method_to_algo[method] == "SVG Steg":
            # prepare data strucures
            svg_data = libstegofile.svg_data_t()
            svg_int = libstegofile.svg_internal_data_t()

            # read file data
            err = libstegofile.io_svg_read(filename, svg_data, svg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.svg_check_capacity(svg_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_svg_cleanup_data(svg_data)
            libstegofile.io_svg_cleanup_internal(svg_int)

        elif method_to_algo[method] == "Echo Hiding":
            # prepare data strucures
            wav_data = libstegofile.wav_data_t()
            wav_int = libstegofile.wav_internal_data_t()

            # read file data
            err = libstegofile.io_wav_read(filename, wav_data, wav_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            if libstego.eh_check_capacity(wav_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_wav_cleanup_data(wav_data)
            libstegofile.io_wav_cleanup_internal(wav_int)


        elif method_to_algo[method] == "Phase Coding":
            # TODO implement
            pass


        elif method_to_algo[method] == "LSB":
            # TODO implement
            pass

        if fits:
            print "best method: " + `method+1`
            return method

    return None
def get_algorithm(filename, msglen, password):
    if filename.endswith("jpeg") or filename.endswith("jpg"):
        # PQ, F5, LSB
        jpeg_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()
        err = libstegofile.io_jpeg_read(filename,jpeg_data, jpeg_int)
#TODO: ERROR (everywhere)

        para = libstegofile.pq_parameter()
        para.header_size = 0
        para.quality = 0

        if libstego.pq_check_capacity(jpeg_data, para) >= msglen:
            libstegofile.jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal(jpg_int)
            return ["PQ",para]

        para = libstegofile.f5_parameter()


        if libstego.f5_check_capacity(jpeg_data, para) >= msglen:
            libstegofile.jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal(jpg_int)
            return ["F5",para]

        para = libstegofile.lsb_parameter()


#        if libstego.lsb_check_capacity(jpeg_data, para) >= msglen:
#            libstegofile.jpeg_cleanup_data(jpeg_data)
#            libstegofile.io_jpeg_cleanup_internal(jpg_int)
#            return ["LSB",para]

        libstegofile.jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_internal(jpg_int)
        return

    elif filename.endswith("gif"):
        # AdvGifshuffle, Gifshuffle, Frirui, Sort/Unsort, LSB
        palette_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)

        para = libstegofile.gifshuffle_parameter()
        if libstego.gifshuffle_check_capacity(palette_data, para) >= msglen:
            return ["Adv. Gifshuffle", para]
# no elif gifshuffle since it has the same capacity that adv gusfhuffle has

        para = libstegofile.frirui_parameter()

        para.method = 0;
        para.size = 100;
        para.password = password
        para.pwlen = len(password)

        #para.method = 1;
        #para.threshold = 574;
        #para.password = password
        #para.pwlen = len(password)

        #para.method = 1;
        #para.threshold = 1148;
        #para.password = password
        #para.pwlen = len(password)

        #para.method = 2;
        #para.password = password
        #para.pwlen = len(password)

        #para.method = 1;
        #para.threshold = 2295;
        #para.password = password
        #para.pwlen = len(password)

        #para.method = 0;
        #para.size = 6;
        #para.password = password
        #para.pwlen = len(password)


        # DONE: multiple parameter sets for frirui from Matthias here!
        if libstego.frirui_check_capacity(palette_data, para) >= msglen:
            return ["Frirui", para]

        para = libstegofile.sortunsort_parameter()
        if libstego.sortunsort_check_capacity(palette_data, para) >= msglen:
            return ["Sort/Unsort", para]

        """para = libstegofile_lsb_parameter_t()
        #TODO: LSB Wrappers for structs like palette_data -> Jan ?
        if libstego.lsb_check_capacity(palette_data, para) >= msglen:
            return ["LSB", para]"""


    elif filename.endswith("png"):
        # CPT, Battlesteg, LSB
        rgb_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()
        err = libstegofile.io_png_read(filename, rgb_data, png_int)

        for i in [2,4,6,8]:
            para = libstegofile.cpt_parameter()
            para.block_width = i;
            para.block_height = i;
            para.password = password
            para.pwlen = len(password)

            if libstegofile.cpt_check_capacity(rgb_data, para) >= msglen:
                return ["CPT", para]

        para = libstegofile.battlesteg_parameter()
        para.startbit = 7
        para.move_away = 3
        para.range = 5
        para.password = password
        para.pwlen = len(password)

        # parameter set "capacity"
        #para = libstegofile.battlesteg_parameter()
        #para.startbit = 6
        #para.move_away = 3
        #para.range = 5
        #para.password = "******"
        #para.pwlen = 8

        if libstegofile.battlesteg_check_capacity(rgb_data, para) >= msglen:
            return ["BattleSteg", para]

        """para = libstegofile.lsb_parameter()
        para.password = password
        para.pwlen = len(password)
        para.select_mode = 2


        if libstegofile.lsb_check_capacity(rgb_data, para) >= msglen:
            return ["LSB", para]"""

    elif filename.endswith("wav"):
        # Phase Coding, Echo Hiding, LSB
        pass

    elif filename.endswith("svg"):
        # SVGSteg

        svg_data = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()
        err = libstegofile.io_svg_read(filename, svg_data, svg_int)

        if err != 0:
            return None

        para = libstegofile.svg_parameter_t()
        para.password = password
        para.pwlen = len(password)
        para.first_embed_digit = 3

        fits = False
        if libstego.svg_check_capacity(svg_dat, para) >= msglen:
            fits = True

        libstegofile.svg_cleanup_data(svg_dat)
        libstegofile.svg_cleanup_internal(svg_int)

        if fits == True:
            return ["SVG", para]
def get_best_method(filename, filetype, msglen, password):
    # setup all methods
    setup_methods(password)

    # get methods for current file type
    num_selected, sel_method = get_methods_for_filetype(filetype)

    for i in [0, num_selected-1]:
        fits = False

        if method_to_algo[i] == "PQ":
            # prepare data strucures
            jpeg_data = libstegofile.jpeg_data_t()
            jpeg_int = libstegofile.jpeg_internal_data_t()

            # read file data
            err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.pq_check_capacity(jpeg_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal(jpg_int)


        if method_to_algo[i] == "F5":
            # prepare data strucures
            jpeg_data = libstegofile.jpeg_data_t()
            jpeg_int = libstegofile.jpeg_internal_data_t()

            # read file data
            err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.f5_check_capacity(jpeg_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.jpeg_cleanup_data(jpeg_data)
            libstegofile.io_jpeg_cleanup_internal(jpg_int)


        if method_to_algo[i] in ["Adv. Gifshuffle", "Gifshuffle"]:
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.gifshuffle_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)


        if method_to_algo[i] == "Frirui":
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.frirui_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)


        if method_to_algo[i] == "Sort/Unsort":
            # prepare data strucures
            palette_data = libstegofile.palette_data_t()
            gif_int = libstegofile.gif_internal_data_t()

            # read file data
            err = libstegofile.io_gif_read(filename, palette_data, gif_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.sortunsort_check_capacity(palette_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_gif_cleanup_data(palette_data)
            libstegofile.io_gif_cleanup_internal(gif_int)

        if method_to_algo[i] == "CPT":
            # prepare data strucures
            rgb_data = libstegofile.rgb_data_t()
            png_int = libstegofile.png_internal_data_t()

            # read file data
            err = libstegofile.io_png_read(filename, rgb_data, png_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstegofile.cpt_check_capacity(rgb_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_png_cleanup_data(rgb_data)
            libstegofile.io_png_cleanup_internal(png_int)


        if method_to_algo[i] == "Battlesteg":
            # prepare data strucures
            rgb_data = libstegofile.rgb_data_t()
            png_int = libstegofile.png_internal_data_t()

            # read file data
            err = libstegofile.io_png_read(filename, rgb_data, png_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstegofile.battlesteg_check_capacity(rgb_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.io_png_cleanup_data(rgb_data)
            libstegofile.io_png_cleanup_internal(png_int)


        if method_to_algo[i] == "SVG Steg":
            # prepare data strucures
            svg_data = libstegofile.svg_data_t()
            svg_int = libstegofile.svg_internal_data_t()

            # read file data
            err = libstegofile.io_svg_read(filename, svg_data, svg_int)
            if err != 0:
                # TODO better error handling -> detailed message what went wrong
                # by using the 'lstg_errno' code
                return None

            # check if message fits with the current params
            para = methods[i]
            if libstego.svg_check_capacity(svg_data, para) >= msglen:
                fits = True

            # cleanup
            libstegofile.svg_cleanup_data(svg_data)
            libstegofile.svg_cleanup_internal(svg_int)

        if method_to_algo[i] == "Echo Hiding":
            # TODO implement
            pass


        if method_to_algo[i] == "Phase Coding":
            # TODO implement
            pass


        if method_to_algo[i] == "LSB":
            # TODO implement
            pass

        if fits:
            return i

    return None